diff --git a/auxil/zeek-aux/CMakeLists.txt b/auxil/zeek-aux/CMakeLists.txt index 4778956377..9813e4e788 100644 --- a/auxil/zeek-aux/CMakeLists.txt +++ b/auxil/zeek-aux/CMakeLists.txt @@ -27,23 +27,18 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) # explicitly installed by the user via "make install-aux" macro (AddAuxInstallTarget _target) add_custom_target( - install-${_target} COMMAND ${CMAKE_COMMAND} -E make_directory - ${CMAKE_INSTALL_PREFIX}/bin + install-${_target} COMMAND ${CMAKE_COMMAND} -E make_directory${CMAKE_INSTALL_PREFIX}/bin COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_INSTALL_PREFIX}/bin) add_dependencies(install-${_target} ${_target}) set(AUX_TARGETS install-${_target};${AUX_TARGETS}) set(AUX_TARGETS ${AUX_TARGETS} PARENT_SCOPE) endmacro (AddAuxInstallTarget) -if (NOT ZEEK_MAN_INSTALL_PATH) - set(ZEEK_MAN_INSTALL_PATH ${CMAKE_INSTALL_PREFIX}/share/man) -endif () - add_subdirectory(adtrace) add_subdirectory(zeek-archiver) add_subdirectory(zeek-cut) add_subdirectory(rst) add_custom_target(install-aux - COMMENT "Zeek auxiliary tools installed to ${CMAKE_INSTALL_PREFIX}/bin") + COMMENT "Zeek auxiliary tools installed to ${CMAKE_INSTALL_PREFIX}/bin") add_dependencies(install-aux ${AUX_TARGETS}) diff --git a/auxil/zeek-aux/adtrace/CMakeLists.txt b/auxil/zeek-aux/adtrace/CMakeLists.txt index f26f257c27..a3e691a838 100644 --- a/auxil/zeek-aux/adtrace/CMakeLists.txt +++ b/auxil/zeek-aux/adtrace/CMakeLists.txt @@ -5,4 +5,4 @@ set(adtrace_SRCS adtrace.c) add_executable(adtrace ${adtrace_SRCS}) target_include_directories(adtrace BEFORE PRIVATE ${PCAP_INCLUDE_DIR}) target_link_libraries(adtrace ${PCAP_LIBRARY}) -AddAuxInstallTarget(adtrace) +addauxinstalltarget(adtrace) diff --git a/auxil/zeek-aux/adtrace/adtrace.c b/auxil/zeek-aux/adtrace/adtrace.c index 0faae96039..81f1eb0d91 100644 --- a/auxil/zeek-aux/adtrace/adtrace.c +++ b/auxil/zeek-aux/adtrace/adtrace.c @@ -1,91 +1,91 @@ -#include -#include -#include -#include -#include +// See the file "COPYING" in the main distribution directory for copyright. -#include #include +#include #include +#include +#include +#include +#include +#include -#include "ip.h" -#include "ether.h" +#include "ether.h" #include "ethertype.h" +#include "ip.h" -pcap_t *p; +pcap_t* p; -const u_char* printEAddr(const u_char* pkt, u_char* endp){ - const struct ether_header *ep; - int i=0; - ep = (const struct ether_header*) pkt; +const u_char* printEAddr(const u_char* pkt, u_char* endp) { + const struct ether_header* ep; + int i = 0; + ep = (const struct ether_header*)pkt; - if (pkt+ETHER_HDRLEN > endp || - ntohs(ep->ether_type) != ETHERTYPE_IP){ - return 0; - } + if ( pkt + ETHER_HDRLEN > endp || ntohs(ep->ether_type) != ETHERTYPE_IP ) { + return 0; + } - for (i = 0; i0) putchar(':'); - printf("%02x", ep->ether_shost[i]); - } - putchar (' '); - for (i = 0; i0) putchar(':'); - printf("%02x", ep->ether_dhost[i]); - } - putchar(' '); - return (pkt+ETHER_HDRLEN); + for ( i = 0; i < ETHER_ADDR_LEN; i++ ) { + if ( i > 0 ) + putchar(':'); + printf("%02x", ep->ether_shost[i]); + } + putchar(' '); + for ( i = 0; i < ETHER_ADDR_LEN; i++ ) { + if ( i > 0 ) + putchar(':'); + printf("%02x", ep->ether_dhost[i]); + } + putchar(' '); + return (pkt + ETHER_HDRLEN); } -void printIPAddr(const u_char* pkt, u_char* endp){ - const struct ip* iph; - if (pkt+sizeof(struct ip) > endp) return; - iph = (const struct ip*) pkt; - fputs ((char*) inet_ntoa(iph->ip_src), stdout); - putchar(' '); - puts ((char*) inet_ntoa(iph->ip_dst)); +void printIPAddr(const u_char* pkt, u_char* endp) { + const struct ip* iph; + if ( pkt + sizeof(struct ip) > endp ) + return; + iph = (const struct ip*)pkt; + fputs((char*)inet_ntoa(iph->ip_src), stdout); + putchar(' '); + puts((char*)inet_ntoa(iph->ip_dst)); } -void handler(u_char *user, const struct pcap_pkthdr *head, const u_char *packet){ - u_char* endp; +void handler(u_char* user, const struct pcap_pkthdr* head, const u_char* packet) { + u_char* endp; - endp =(u_char*) packet + head->caplen; - packet = printEAddr(packet, endp); - if (packet) - printIPAddr(packet, endp); + endp = (u_char*)packet + head->caplen; + packet = printEAddr(packet, endp); + if ( packet ) + printIPAddr(packet, endp); } -void usage(char *av[]) -{ - fprintf(stderr,"usage: %s filename \n", av[0]); - exit(1); +void usage(char* av[]) { + fprintf(stderr, "usage: %s filename \n", av[0]); + exit(1); } -int main (int argc, char *argv[]) -{ - char *file; - char errbuf[PCAP_ERRBUF_SIZE]; - u_char* pkt, endp; - struct pcap_pkthdr *head; +int main(int argc, char* argv[]) { + char* file; + char errbuf[PCAP_ERRBUF_SIZE]; + u_char *pkt, endp; + struct pcap_pkthdr* head; - if ( argc != 2 ) - usage(argv); + if ( argc != 2 ) + usage(argv); - file = argv[1]; + file = argv[1]; - p = pcap_open_offline(file, errbuf); - if(p==NULL){ - fprintf (stderr, "cannot open %s: %s\n", file, errbuf); - exit(2); - } - - if (pcap_datalink(p) != DLT_EN10MB){ - fputs ("sorry, currently only ethernet links supported\n", stderr); - exit(1); //if it is not ethernet we are watching we won't have MACs - } + p = pcap_open_offline(file, errbuf); + if ( p == NULL ) { + fprintf(stderr, "cannot open %s: %s\n", file, errbuf); + exit(2); + } - pcap_loop(p, -1, handler, NULL); - pcap_close(p); - return(0); + if ( pcap_datalink(p) != DLT_EN10MB ) { + fputs("sorry, currently only ethernet links supported\n", stderr); + exit(1); // if it is not ethernet we are watching we won't have MACs + } + + pcap_loop(p, -1, handler, NULL); + pcap_close(p); + return (0); } - diff --git a/auxil/zeek-aux/adtrace/ether.h b/auxil/zeek-aux/adtrace/ether.h index 77d0377945..f3c1bccf58 100644 --- a/auxil/zeek-aux/adtrace/ether.h +++ b/auxil/zeek-aux/adtrace/ether.h @@ -34,20 +34,20 @@ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95 */ -#define ETHERMTU 1500 +#define ETHERMTU 1500 /* * The number of bytes in an ethernet (MAC) address. */ -#define ETHER_ADDR_LEN 6 +#define ETHER_ADDR_LEN 6 /* * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header. */ -struct ether_header { - u_int8_t ether_dhost[ETHER_ADDR_LEN]; - u_int8_t ether_shost[ETHER_ADDR_LEN]; - u_int16_t ether_type; +struct ether_header { + u_int8_t ether_dhost[ETHER_ADDR_LEN]; + u_int8_t ether_shost[ETHER_ADDR_LEN]; + u_int16_t ether_type; }; /* @@ -56,4 +56,4 @@ struct ether_header { * for example, so "sizeof (struct ether_header)" may not give the right * answer. */ -#define ETHER_HDRLEN 14 +#define ETHER_HDRLEN 14 diff --git a/auxil/zeek-aux/adtrace/ethertype.h b/auxil/zeek-aux/adtrace/ethertype.h index 1f6aab6776..8a096d57f1 100644 --- a/auxil/zeek-aux/adtrace/ethertype.h +++ b/auxil/zeek-aux/adtrace/ethertype.h @@ -34,89 +34,89 @@ */ #ifndef ETHERTYPE_PUP -#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ +#define ETHERTYPE_PUP 0x0200 /* PUP protocol */ #endif #ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#define ETHERTYPE_IP 0x0800 /* IP protocol */ #endif #ifndef ETHERTYPE_ARP -#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ +#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */ #endif #ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ +#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */ #endif #ifndef ETHERTYPE_NS -#define ETHERTYPE_NS 0x0600 +#define ETHERTYPE_NS 0x0600 #endif -#ifndef ETHERTYPE_SPRITE -#define ETHERTYPE_SPRITE 0x0500 +#ifndef ETHERTYPE_SPRITE +#define ETHERTYPE_SPRITE 0x0500 #endif #ifndef ETHERTYPE_TRAIL -#define ETHERTYPE_TRAIL 0x1000 +#define ETHERTYPE_TRAIL 0x1000 #endif -#ifndef ETHERTYPE_MOPDL -#define ETHERTYPE_MOPDL 0x6001 +#ifndef ETHERTYPE_MOPDL +#define ETHERTYPE_MOPDL 0x6001 #endif -#ifndef ETHERTYPE_MOPRC -#define ETHERTYPE_MOPRC 0x6002 +#ifndef ETHERTYPE_MOPRC +#define ETHERTYPE_MOPRC 0x6002 #endif -#ifndef ETHERTYPE_DN -#define ETHERTYPE_DN 0x6003 +#ifndef ETHERTYPE_DN +#define ETHERTYPE_DN 0x6003 #endif -#ifndef ETHERTYPE_LAT -#define ETHERTYPE_LAT 0x6004 +#ifndef ETHERTYPE_LAT +#define ETHERTYPE_LAT 0x6004 #endif #ifndef ETHERTYPE_SCA -#define ETHERTYPE_SCA 0x6007 +#define ETHERTYPE_SCA 0x6007 #endif #ifndef ETHERTYPE_REVARP -#define ETHERTYPE_REVARP 0x8035 +#define ETHERTYPE_REVARP 0x8035 #endif -#ifndef ETHERTYPE_LANBRIDGE -#define ETHERTYPE_LANBRIDGE 0x8038 +#ifndef ETHERTYPE_LANBRIDGE +#define ETHERTYPE_LANBRIDGE 0x8038 #endif -#ifndef ETHERTYPE_DECDNS -#define ETHERTYPE_DECDNS 0x803c +#ifndef ETHERTYPE_DECDNS +#define ETHERTYPE_DECDNS 0x803c #endif -#ifndef ETHERTYPE_DECDTS -#define ETHERTYPE_DECDTS 0x803e +#ifndef ETHERTYPE_DECDTS +#define ETHERTYPE_DECDTS 0x803e #endif -#ifndef ETHERTYPE_VEXP -#define ETHERTYPE_VEXP 0x805b +#ifndef ETHERTYPE_VEXP +#define ETHERTYPE_VEXP 0x805b #endif -#ifndef ETHERTYPE_VPROD -#define ETHERTYPE_VPROD 0x805c +#ifndef ETHERTYPE_VPROD +#define ETHERTYPE_VPROD 0x805c #endif #ifndef ETHERTYPE_ATALK -#define ETHERTYPE_ATALK 0x809b +#define ETHERTYPE_ATALK 0x809b #endif #ifndef ETHERTYPE_AARP -#define ETHERTYPE_AARP 0x80f3 +#define ETHERTYPE_AARP 0x80f3 #endif -#ifndef ETHERTYPE_8021Q -#define ETHERTYPE_8021Q 0x8100 +#ifndef ETHERTYPE_8021Q +#define ETHERTYPE_8021Q 0x8100 #endif #ifndef ETHERTYPE_IPX -#define ETHERTYPE_IPX 0x8137 +#define ETHERTYPE_IPX 0x8137 #endif #ifndef ETHERTYPE_IPV6 -#define ETHERTYPE_IPV6 0x86dd +#define ETHERTYPE_IPV6 0x86dd #endif #ifndef ETHERTYPE_PPP -#define ETHERTYPE_PPP 0x880b +#define ETHERTYPE_PPP 0x880b #endif -#ifndef ETHERTYPE_MPLS -#define ETHERTYPE_MPLS 0x8847 +#ifndef ETHERTYPE_MPLS +#define ETHERTYPE_MPLS 0x8847 #endif -#ifndef ETHERTYPE_MPLS_MULTI -#define ETHERTYPE_MPLS_MULTI 0x8848 +#ifndef ETHERTYPE_MPLS_MULTI +#define ETHERTYPE_MPLS_MULTI 0x8848 #endif #ifndef ETHERTYPE_PPPOED -#define ETHERTYPE_PPPOED 0x8863 +#define ETHERTYPE_PPPOED 0x8863 #endif #ifndef ETHERTYPE_PPPOES -#define ETHERTYPE_PPPOES 0x8864 +#define ETHERTYPE_PPPOES 0x8864 #endif -#ifndef ETHERTYPE_LOOPBACK -#define ETHERTYPE_LOOPBACK 0x9000 +#ifndef ETHERTYPE_LOOPBACK +#define ETHERTYPE_LOOPBACK 0x9000 #endif diff --git a/auxil/zeek-aux/adtrace/ip.h b/auxil/zeek-aux/adtrace/ip.h index 3d930537c9..15c1441350 100644 --- a/auxil/zeek-aux/adtrace/ip.h +++ b/auxil/zeek-aux/adtrace/ip.h @@ -38,7 +38,7 @@ * Definitions for internet protocol version 4. * Per RFC 791, September 1981. */ -#define IPVERSION 4 +#define IPVERSION 4 /* * Structure of an internet header, naked of options. @@ -48,112 +48,112 @@ * against negative integers quite easily, and fail in subtle ways. */ struct ip { - u_int8_t ip_vhl; /* header length, version */ -#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) -#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) - u_int8_t ip_tos; /* type of service */ - u_int16_t ip_len; /* total length */ - u_int16_t ip_id; /* identification */ - u_int16_t ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* dont fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u_int8_t ip_ttl; /* time to live */ - u_int8_t ip_p; /* protocol */ - u_int16_t ip_sum; /* checksum */ - struct in_addr ip_src,ip_dst; /* source and dest address */ + u_int8_t ip_vhl; /* header length, version */ +#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4) +#define IP_HL(ip) ((ip)->ip_vhl & 0x0f) + u_int8_t ip_tos; /* type of service */ + u_int16_t ip_len; /* total length */ + u_int16_t ip_id; /* identification */ + u_int16_t ip_off; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + u_int8_t ip_ttl; /* time to live */ + u_int8_t ip_p; /* protocol */ + u_int16_t ip_sum; /* checksum */ + struct in_addr ip_src, ip_dst; /* source and dest address */ }; -#define IP_MAXPACKET 65535 /* maximum packet size */ +#define IP_MAXPACKET 65535 /* maximum packet size */ /* * Definitions for IP type of service (ip_tos) */ -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 +#define IPTOS_LOWDELAY 0x10 +#define IPTOS_THROUGHPUT 0x08 +#define IPTOS_RELIABILITY 0x04 /* * Definitions for IP precedence (also in ip_tos) (hopefully unused) */ -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 +#define IPTOS_PREC_NETCONTROL 0xe0 +#define IPTOS_PREC_INTERNETCONTROL 0xc0 +#define IPTOS_PREC_CRITIC_ECP 0xa0 +#define IPTOS_PREC_FLASHOVERRIDE 0x80 +#define IPTOS_PREC_FLASH 0x60 +#define IPTOS_PREC_IMMEDIATE 0x40 +#define IPTOS_PREC_PRIORITY 0x20 +#define IPTOS_PREC_ROUTINE 0x00 /* * Definitions for options. */ -#define IPOPT_COPIED(o) ((o)&0x80) -#define IPOPT_CLASS(o) ((o)&0x60) -#define IPOPT_NUMBER(o) ((o)&0x1f) +#define IPOPT_COPIED(o) ((o) & 0x80) +#define IPOPT_CLASS(o) ((o) & 0x60) +#define IPOPT_NUMBER(o) ((o) & 0x1f) -#define IPOPT_CONTROL 0x00 -#define IPOPT_RESERVED1 0x20 -#define IPOPT_DEBMEAS 0x40 -#define IPOPT_RESERVED2 0x60 +#define IPOPT_CONTROL 0x00 +#define IPOPT_RESERVED1 0x20 +#define IPOPT_DEBMEAS 0x40 +#define IPOPT_RESERVED2 0x60 -#define IPOPT_EOL 0 /* end of option list */ -#define IPOPT_NOP 1 /* no operation */ +#define IPOPT_EOL 0 /* end of option list */ +#define IPOPT_NOP 1 /* no operation */ -#define IPOPT_RR 7 /* record packet route */ -#define IPOPT_TS 68 /* timestamp */ -#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ -#define IPOPT_LSRR 131 /* loose source route */ -#define IPOPT_SATID 136 /* satnet id */ -#define IPOPT_SSRR 137 /* strict source route */ +#define IPOPT_RR 7 /* record packet route */ +#define IPOPT_TS 68 /* timestamp */ +#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */ +#define IPOPT_LSRR 131 /* loose source route */ +#define IPOPT_SATID 136 /* satnet id */ +#define IPOPT_SSRR 137 /* strict source route */ /* * Offsets to fields in options other than EOL and NOP. */ -#define IPOPT_OPTVAL 0 /* option ID */ -#define IPOPT_OLEN 1 /* option length */ -#define IPOPT_OFFSET 2 /* offset within option */ -#define IPOPT_MINOFF 4 /* min value of above */ +#define IPOPT_OPTVAL 0 /* option ID */ +#define IPOPT_OLEN 1 /* option length */ +#define IPOPT_OFFSET 2 /* offset within option */ +#define IPOPT_MINOFF 4 /* min value of above */ /* * Time stamp option structure. */ -struct ip_timestamp { - u_int8_t ipt_code; /* IPOPT_TS */ - u_int8_t ipt_len; /* size of structure (variable) */ - u_int8_t ipt_ptr; /* index of current entry */ - u_int8_t ipt_oflwflg; /* flags, overflow counter */ -#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4) -#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f) - union ipt_timestamp { - u_int32_t ipt_time[1]; - struct ipt_ta { - struct in_addr ipt_addr; - u_int32_t ipt_time; - } ipt_ta[1]; - } ipt_timestamp; +struct ip_timestamp { + u_int8_t ipt_code; /* IPOPT_TS */ + u_int8_t ipt_len; /* size of structure (variable) */ + u_int8_t ipt_ptr; /* index of current entry */ + u_int8_t ipt_oflwflg; /* flags, overflow counter */ +#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4) +#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f) + union ipt_timestamp { + u_int32_t ipt_time[1]; + struct ipt_ta { + struct in_addr ipt_addr; + u_int32_t ipt_time; + } ipt_ta[1]; + } ipt_timestamp; }; /* flag bits for ipt_flg */ -#define IPOPT_TS_TSONLY 0 /* timestamps only */ -#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ -#define IPOPT_TS_PRESPEC 3 /* specified modules only */ +#define IPOPT_TS_TSONLY 0 /* timestamps only */ +#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ +#define IPOPT_TS_PRESPEC 3 /* specified modules only */ /* bits for security (not byte swapped) */ -#define IPOPT_SECUR_UNCLASS 0x0000 -#define IPOPT_SECUR_CONFID 0xf135 -#define IPOPT_SECUR_EFTO 0x789a -#define IPOPT_SECUR_MMMM 0xbc4d -#define IPOPT_SECUR_RESTR 0xaf13 -#define IPOPT_SECUR_SECRET 0xd788 -#define IPOPT_SECUR_TOPSECRET 0x6bc5 +#define IPOPT_SECUR_UNCLASS 0x0000 +#define IPOPT_SECUR_CONFID 0xf135 +#define IPOPT_SECUR_EFTO 0x789a +#define IPOPT_SECUR_MMMM 0xbc4d +#define IPOPT_SECUR_RESTR 0xaf13 +#define IPOPT_SECUR_SECRET 0xd788 +#define IPOPT_SECUR_TOPSECRET 0x6bc5 /* * Internet implementation parameters. */ -#define MAXTTL 255 /* maximum time to live (seconds) */ -#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ -#define IPFRAGTTL 60 /* time to live for frags, slowhz */ -#define IPTTLDEC 1 /* subtracted when forwarding */ +#define MAXTTL 255 /* maximum time to live (seconds) */ +#define IPDEFTTL 64 /* default ttl, from RFC 1340 */ +#define IPFRAGTTL 60 /* time to live for frags, slowhz */ +#define IPTTLDEC 1 /* subtracted when forwarding */ -#define IP_MSS 576 /* default maximum segment size */ +#define IP_MSS 576 /* default maximum segment size */ diff --git a/auxil/zeek-aux/plugin-support/skeleton/src/Plugin.cc b/auxil/zeek-aux/plugin-support/skeleton/src/Plugin.cc index 60d3b79bbf..e15a6231b6 100644 --- a/auxil/zeek-aux/plugin-support/skeleton/src/Plugin.cc +++ b/auxil/zeek-aux/plugin-support/skeleton/src/Plugin.cc @@ -5,13 +5,12 @@ namespace plugin { namespace @PLUGIN_NAMESPACE@_@PLUGIN_NAME@ { Plugin plugin; } using namespace plugin::@PLUGIN_NAMESPACE@_@PLUGIN_NAME@; -zeek::plugin::Configuration Plugin::Configure() - { - zeek::plugin::Configuration config; - config.name = "@PLUGIN_NAMESPACE@::@PLUGIN_NAME@"; - config.description = ""; - config.version.major = 0; - config.version.minor = 1; - config.version.patch = 0; - return config; - } +zeek::plugin::Configuration Plugin::Configure() { + zeek::plugin::Configuration config; + config.name = "@PLUGIN_NAMESPACE@::@PLUGIN_NAME@"; + config.description = ""; + config.version.major = 0; + config.version.minor = 1; + config.version.patch = 0; + return config; +} diff --git a/auxil/zeek-aux/rst/CMakeLists.txt b/auxil/zeek-aux/rst/CMakeLists.txt index 6859379ab9..f21c9e0695 100644 --- a/auxil/zeek-aux/rst/CMakeLists.txt +++ b/auxil/zeek-aux/rst/CMakeLists.txt @@ -2,4 +2,4 @@ set(rst_SRCS rst.c) add_executable(rst ${rst_SRCS}) -AddAuxInstallTarget(rst) +addauxinstalltarget(rst) diff --git a/auxil/zeek-aux/rst/rst.c b/auxil/zeek-aux/rst/rst.c index 183ca7e60b..3c4fb1ba57 100644 --- a/auxil/zeek-aux/rst/rst.c +++ b/auxil/zeek-aux/rst/rst.c @@ -30,379 +30,343 @@ static const char copyright[] = #define _BSD_SOURCE /* Deprecated, but still needed by older Linux. */ #endif +// clang-format off +// This file needs to come before some of the files below or FreeBSD won't find +// some of the types it needs. #include -#include - -#include +// clang-format on +#include +#include #include +#include #include #include - -#include - -#include #include #include #include +#include #include #include "config.h" /* Forwards */ -void gripe(const char *, const char *); -void pgripe(const char *); -uint16_t in_cksum(register uint16_t *, register int); -int ones_complement_checksum(const void *, int, uint32_t); -int tcp_checksum(const struct ip *, const struct tcphdr *, int); -void send_pkt(int, struct in_addr, int, uint32_t, struct in_addr, - int, uint32_t, int, int, int, int, const char *); -void terminate(int, const char *, int, uint32_t, const char *, - int, uint32_t, int, int, int, int, const char *); +void gripe(const char*, const char*); +void pgripe(const char*); +uint16_t in_cksum(register uint16_t*, register int); +int ones_complement_checksum(const void*, int, uint32_t); +int tcp_checksum(const struct ip*, const struct tcphdr*, int); +void send_pkt(int, struct in_addr, int, uint32_t, struct in_addr, int, uint32_t, int, int, int, int, const char*); +void terminate(int, const char*, int, uint32_t, const char*, int, uint32_t, int, int, int, int, const char*); void usage(void); -int main(int, char **); +int main(int, char**); -const char *prog_name; +const char* prog_name; -void gripe(const char *fmt, const char *arg) -{ - fprintf(stderr, "%s: ", prog_name); - fprintf(stderr, fmt, arg); - fprintf(stderr, "\n"); +void gripe(const char* fmt, const char* arg) { + fprintf(stderr, "%s: ", prog_name); + fprintf(stderr, fmt, arg); + fprintf(stderr, "\n"); } -void pgripe(const char *msg) -{ - fprintf(stderr, "%s: %s (%s)\n", prog_name, msg, strerror(errno)); - exit(1); +void pgripe(const char* msg) { + fprintf(stderr, "%s: %s (%s)\n", prog_name, msg, strerror(errno)); + exit(1); } /* * Checksum routine for Internet Protocol family headers (C Version) */ -uint16_t -in_cksum(register uint16_t *addr, register int len) -{ - register int nleft = len; - register uint16_t *w = addr; - register uint16_t answer; - register int sum = 0; +uint16_t in_cksum(register uint16_t* addr, register int len) { + register int nleft = len; + register uint16_t* w = addr; + register uint16_t answer; + register int sum = 0; - /* - * Our algorithm is simple, using a 32 bit accumulator (sum), - * we add sequential 16 bit words to it, and at the end, fold - * back all the carry bits from the top 16 bits into the lower - * 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } + /* + * Our algorithm is simple, using a 32 bit accumulator (sum), + * we add sequential 16 bit words to it, and at the end, fold + * back all the carry bits from the top 16 bits into the lower + * 16 bits. + */ + while ( nleft > 1 ) { + sum += *w++; + nleft -= 2; + } - /* mop up an odd byte, if necessary */ - if (nleft == 1) - sum += *(u_char *)w; + /* mop up an odd byte, if necessary */ + if ( nleft == 1 ) + sum += *(u_char*)w; - /* - * add back carry outs from top 16 bits to low 16 bits - */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return (answer); + /* + * add back carry outs from top 16 bits to low 16 bits + */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + answer = ~sum; /* truncate to 16 bits */ + return (answer); } // - adapted from tcpdump // Returns the ones-complement checksum of a chunk of b short-aligned bytes. -int ones_complement_checksum(const void *p, int b, uint32_t sum) -{ - const uint16_t *sp = (uint16_t *) p; // better be aligned! +int ones_complement_checksum(const void* p, int b, uint32_t sum) { + const uint16_t* sp = (uint16_t*)p; // better be aligned! - b /= 2; // convert to count of short's + b /= 2; // convert to count of short's - /* No need for endian conversions. */ - while ( --b >= 0 ) - sum += *sp++; + /* No need for endian conversions. */ + while ( --b >= 0 ) + sum += *sp++; - while ( sum > 0xffff ) - sum = (sum & 0xffff) + (sum >> 16); + while ( sum > 0xffff ) + sum = (sum & 0xffff) + (sum >> 16); - return sum; + return sum; } -int tcp_checksum(const struct ip *ip, const struct tcphdr *tp, int len) -{ - int tcp_len = tp->th_off * 4 + len; - uint32_t sum = 0; +int tcp_checksum(const struct ip* ip, const struct tcphdr* tp, int len) { + int tcp_len = tp->th_off * 4 + len; + uint32_t sum = 0; - // There's a weird bug in some versions of GCC where building with -O2 or - // higher will cause the initialization here to get optimized away, and - // lead to the compiler warning that this variable is used uninitialized. - // Using 'volatile' here short-circuits that optimization and fixes the - // warning. - volatile uint32_t addl_pseudo = 0; + // There's a weird bug in some versions of GCC where building with -O2 or + // higher will cause the initialization here to get optimized away, and + // lead to the compiler warning that this variable is used uninitialized. + // Using 'volatile' here short-circuits that optimization and fixes the + // warning. + volatile uint32_t addl_pseudo = 0; - if ( len % 2 == 1 ) - // Add in pad byte. - sum = htons(((const u_char*) tp)[tcp_len - 1] << 8); - else - sum = 0; + if ( len % 2 == 1 ) + // Add in pad byte. + sum = htons(((const u_char*)tp)[tcp_len - 1] << 8); + else + sum = 0; - sum = ones_complement_checksum((void*) &ip->ip_src.s_addr, 4, sum); - sum = ones_complement_checksum((void*) &ip->ip_dst.s_addr, 4, sum); + sum = ones_complement_checksum((void*)&ip->ip_src.s_addr, 4, sum); + sum = ones_complement_checksum((void*)&ip->ip_dst.s_addr, 4, sum); - addl_pseudo = (htons(IPPROTO_TCP) << 16) | htons((unsigned short) tcp_len); + addl_pseudo = (htons(IPPROTO_TCP) << 16) | htons((unsigned short)tcp_len); - sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum); - sum = ones_complement_checksum((void*) tp, tcp_len, sum); + sum = ones_complement_checksum((void*)&addl_pseudo, 4, sum); + sum = ones_complement_checksum((void*)tp, tcp_len, sum); - return sum; + return sum; } -void send_pkt(int s, struct in_addr from, int from_port, uint32_t from_seq, - struct in_addr to, int to_port, uint32_t to_seq, - int size, int redundancy, int delay, int flags, - const char *inject) -{ - int cc; - int pktlen = 40 + size; - const int max_injection_size = 4096; - char *pkt = malloc(pktlen + max_injection_size + 1024 /* slop */); - struct ip *ip = (struct ip *) pkt; - struct tcphdr *tcp = (struct tcphdr *) &pkt[20]; +void send_pkt(int s, struct in_addr from, int from_port, uint32_t from_seq, struct in_addr to, int to_port, + uint32_t to_seq, int size, int redundancy, int delay, int flags, const char* inject) { + int cc; + int pktlen = 40 + size; + const int max_injection_size = 4096; + char* pkt = malloc(pktlen + max_injection_size + 1024 /* slop */); + struct ip* ip = (struct ip*)pkt; + struct tcphdr* tcp = (struct tcphdr*)&pkt[20]; - if ( ! pkt ) - pgripe("couldn't malloc memory"); + if ( ! pkt ) + pgripe("couldn't malloc memory"); - if ( inject && *inject ) { - size = strlen(inject); + if ( inject && *inject ) { + size = strlen(inject); - if ( size > max_injection_size ) - gripe("injection text too large%s", ""); + if ( size > max_injection_size ) + gripe("injection text too large%s", ""); - pktlen = 40 + size; - } + pktlen = 40 + size; + } - memset(pkt, 0, pktlen); + memset(pkt, 0, pktlen); - ip->ip_v = IPVERSION; - ip->ip_len = pktlen; /* on FreeBSD, don't use htons(); YMMV */ - ip->ip_off = 0; - ip->ip_src = from; - ip->ip_dst = to; - ip->ip_hl = 5; - ip->ip_p = IPPROTO_TCP; - ip->ip_ttl = 255; - ip->ip_id = 0; + ip->ip_v = IPVERSION; + ip->ip_len = pktlen; /* on FreeBSD, don't use htons(); YMMV */ + ip->ip_off = 0; + ip->ip_src = from; + ip->ip_dst = to; + ip->ip_hl = 5; + ip->ip_p = IPPROTO_TCP; + ip->ip_ttl = 255; + ip->ip_id = 0; - ip->ip_sum = in_cksum((uint16_t *) ip, sizeof(*ip)); + ip->ip_sum = in_cksum((uint16_t*)ip, sizeof(*ip)); - if (ip->ip_sum == 0) - ip->ip_sum = 0xffff; + if ( ip->ip_sum == 0 ) + ip->ip_sum = 0xffff; - tcp->th_sport = htons(from_port); - tcp->th_dport = htons(to_port); - tcp->th_seq = htonl(from_seq); - tcp->th_ack = htonl(to_seq); - tcp->th_off = 5; - tcp->th_flags = flags; - tcp->th_win = 0; - tcp->th_urp = 0; - tcp->th_sum = 0; + tcp->th_sport = htons(from_port); + tcp->th_dport = htons(to_port); + tcp->th_seq = htonl(from_seq); + tcp->th_ack = htonl(to_seq); + tcp->th_off = 5; + tcp->th_flags = flags; + tcp->th_win = 0; + tcp->th_urp = 0; + tcp->th_sum = 0; - if ( inject && *inject ) { - char *payload = &pkt[40]; - strcpy(payload, inject); + if ( inject && *inject ) { + char* payload = &pkt[40]; + strcpy(payload, inject); + } + else if ( size > 0 ) { + const char* fill_string = (inject && *inject) ? inject : "BRO-RST\n"; + char* payload = &pkt[40]; + int n = strlen(fill_string); + int i; + for ( i = size; i > n + 1; i -= n ) { + strcpy(payload, fill_string); + payload += n; + } - } else if ( size > 0 ) - { - const char *fill_string = - (inject && *inject) ? inject : "BRO-RST\n"; - char *payload = &pkt[40]; - int n = strlen(fill_string); - int i; - for ( i = size; i > n + 1; i -= n ) - { - strcpy(payload, fill_string); - payload += n; - } + for ( ; i > 0; --i ) + *(payload++) = '\n'; + } - for ( ; i > 0; --i ) - *(payload++) = '\n'; - } + tcp->th_sum = ~tcp_checksum(ip, tcp, size); - tcp->th_sum = ~tcp_checksum(ip, tcp, size); + while ( redundancy-- > 0 ) { + cc = send(s, (char*)ip, pktlen, 0); + if ( cc < 0 || cc != pktlen ) + pgripe("problem in sendto()"); + usleep(delay * 1000); + } - while ( redundancy-- > 0 ) - { - cc = send(s, (char *) ip, pktlen, 0); - if (cc < 0 || cc != pktlen) - pgripe("problem in sendto()"); - usleep(delay * 1000); - } - - free(pkt); + free(pkt); } -void terminate(int s, const char *from_addr, int from_port, uint32_t from_seq, - const char *to_addr, int to_port, uint32_t to_seq, - int num, int redundancy, int stride, int delay, - const char *inject) -{ - struct sockaddr_in where_from, where_to; - struct sockaddr_in *from = (struct sockaddr_in *) &where_from; - struct sockaddr_in *to = (struct sockaddr_in *) &where_to; +void terminate(int s, const char* from_addr, int from_port, uint32_t from_seq, const char* to_addr, int to_port, + uint32_t to_seq, int num, int redundancy, int stride, int delay, const char* inject) { + struct sockaddr_in where_from, where_to; + struct sockaddr_in* from = (struct sockaddr_in*)&where_from; + struct sockaddr_in* to = (struct sockaddr_in*)&where_to; - memset(from, 0, sizeof(*from)); - memset(to, 0, sizeof(*to)); + memset(from, 0, sizeof(*from)); + memset(to, 0, sizeof(*to)); #ifdef SIN_LEN - from->sin_len = to->sin_len = sizeof(*to); + from->sin_len = to->sin_len = sizeof(*to); #endif /* SIN_LEN */ - from->sin_family = to->sin_family = AF_INET; + from->sin_family = to->sin_family = AF_INET; - if ( inet_aton(from_addr, (struct in_addr *) &from->sin_addr) == 0 ) - gripe("bad from address %s", from_addr); - if ( inet_aton(to_addr, (struct in_addr *) &to->sin_addr) == 0 ) - gripe("bad to address %s", to_addr); + if ( inet_aton(from_addr, (struct in_addr*)&from->sin_addr) == 0 ) + gripe("bad from address %s", from_addr); + if ( inet_aton(to_addr, (struct in_addr*)&to->sin_addr) == 0 ) + gripe("bad to address %s", to_addr); - if ( connect(s, (struct sockaddr *) &where_to, sizeof(where_to)) < 0 ) - pgripe("can't connect"); + if ( connect(s, (struct sockaddr*)&where_to, sizeof(where_to)) < 0 ) + pgripe("can't connect"); - while ( num-- > 0 ) - { - send_pkt(s, from->sin_addr, from_port, from_seq, - to->sin_addr, to_port, to_seq, 0, redundancy, delay, - (*inject ? 0 : TH_RST) | TH_ACK, inject); + while ( num-- > 0 ) { + send_pkt(s, from->sin_addr, from_port, from_seq, to->sin_addr, to_port, to_seq, 0, redundancy, delay, + (*inject ? 0 : TH_RST) | TH_ACK, inject); - if ( num > 0 && stride > 1 ) - send_pkt(s, from->sin_addr, from_port, from_seq, - to->sin_addr, to_port, to_seq, stride, - redundancy, delay, TH_ACK, inject); + if ( num > 0 && stride > 1 ) + send_pkt(s, from->sin_addr, from_port, from_seq, to->sin_addr, to_port, to_seq, stride, redundancy, delay, + TH_ACK, inject); - from_seq += stride; - } + from_seq += stride; + } } -void usage() -{ +void usage() { #if defined(__linux__) - fprintf(stderr, "%s [-R] [-I text-to-inject] [-i interface] [-d delay-msec] [-n num] [-r redundancy] [-s stride] from_addr from_port from_seq to_addr to_port to_seq\n", prog_name); + fprintf(stderr, + "%s [-R] [-I text-to-inject] [-i interface] [-d delay-msec] [-n num] [-r redundancy] [-s stride] from_addr " + "from_port from_seq to_addr to_port to_seq\n", + prog_name); #else - fprintf(stderr, "%s [-R] [-I text-to-inject] [-d delay-msec] [-n num] [-r redundancy] [-s stride] from_addr from_port from_seq to_addr to_port to_seq\n", prog_name); + fprintf(stderr, + "%s [-R] [-I text-to-inject] [-d delay-msec] [-n num] [-r redundancy] [-s stride] from_addr from_port " + "from_seq to_addr to_port to_seq\n", + prog_name); #endif - exit(0); + exit(0); } -int main(int argc, char **argv) -{ - extern char* optarg; - extern int optind, opterr; - const char *from_addr, *to_addr; - char inject[8192]; - int from_port, to_port; - uint32_t from_seq, to_seq; - int delay = 0.0; - int redundancy = 1; - int num = 1; - int stride = 1; - int reverse = 0; - int s; - int on = 1; - int op; +int main(int argc, char** argv) { + extern char* optarg; + extern int optind, opterr; + const char *from_addr, *to_addr; + char inject[8192]; + int from_port, to_port; + uint32_t from_seq, to_seq; + int delay = 0.0; + int redundancy = 1; + int num = 1; + int stride = 1; + int reverse = 0; + int s; + int on = 1; + int op; - prog_name = argv[0]; + prog_name = argv[0]; - opterr = 0; + opterr = 0; - inject[0] = 0; + inject[0] = 0; #if defined(__linux__) - char *interface = NULL; + char* interface = NULL; - while ( (op = getopt(argc, argv, "RI:i:d:n:r:s:")) != EOF ) + while ( (op = getopt(argc, argv, "RI:i:d:n:r:s:")) != EOF ) #else - while ( (op = getopt(argc, argv, "RI:d:n:r:s:")) != EOF ) + while ( (op = getopt(argc, argv, "RI:d:n:r:s:")) != EOF ) #endif - switch ( op ) { - case 'R': - reverse = 1; - break; + switch ( op ) { + case 'R': reverse = 1; break; - case 'I': - { - char *ap = optarg; - char *ip; - for ( ip = inject; *ap; ++ip, ++ap ) { - if ( ap[0] == '\\' && ap[1] == 'n' ) - *ip = '\n', ++ap; - else - *ip = *ap; - } - } - break; + case 'I': { + char* ap = optarg; + char* ip; + for ( ip = inject; *ap; ++ip, ++ap ) { + if ( ap[0] == '\\' && ap[1] == 'n' ) + *ip = '\n', ++ap; + else + *ip = *ap; + } + } break; #if defined(__linux__) - case 'i': - interface = optarg; - break; + case 'i': interface = optarg; break; #endif - case 'd': - delay = atoi(optarg); - break; + case 'd': delay = atoi(optarg); break; - case 'n': - num = atoi(optarg); - break; + case 'n': num = atoi(optarg); break; - case 'r': - redundancy = atoi(optarg); - break; + case 'r': redundancy = atoi(optarg); break; - case 's': - stride = atoi(optarg); - break; + case 's': stride = atoi(optarg); break; - default: - usage(); - break; - } + default: usage(); break; + } - if ( argc - optind != 6 ) - usage(); + if ( argc - optind != 6 ) + usage(); - s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); - if ( s < 0 ) - pgripe("couldn't create raw socket"); + s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + if ( s < 0 ) + pgripe("couldn't create raw socket"); - if ( setuid(getuid()) ) - pgripe("couldn't lower privileges"); + if ( setuid(getuid()) ) + pgripe("couldn't lower privileges"); - if ( setsockopt(s, 0, IP_HDRINCL, (char *) &on, sizeof(on)) < 0 ) - pgripe("can't turn on IP_HDRINCL"); + if ( setsockopt(s, 0, IP_HDRINCL, (char*)&on, sizeof(on)) < 0 ) + pgripe("can't turn on IP_HDRINCL"); #if defined(__linux__) - if ( interface ){ - if ( setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0 ) - pgripe("can't set interface"); - } + if ( interface ) { + if ( setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0 ) + pgripe("can't set interface"); + } #endif - from_addr = argv[optind++]; - from_port = atoi(argv[optind++]); - from_seq = strtoul(argv[optind++], 0, 10); + from_addr = argv[optind++]; + from_port = atoi(argv[optind++]); + from_seq = strtoul(argv[optind++], 0, 10); - to_addr = argv[optind++]; - to_port = atoi(argv[optind++]); - to_seq = strtoul(argv[optind++], 0, 10); + to_addr = argv[optind++]; + to_port = atoi(argv[optind++]); + to_seq = strtoul(argv[optind++], 0, 10); - if ( reverse ) - terminate(s, to_addr, to_port, to_seq, - from_addr, from_port, from_seq, - num, redundancy, stride, delay, inject); - else - terminate(s, from_addr, from_port, from_seq, - to_addr, to_port, to_seq, - num, redundancy, stride, delay, inject); + if ( reverse ) + terminate(s, to_addr, to_port, to_seq, from_addr, from_port, from_seq, num, redundancy, stride, delay, inject); + else + terminate(s, from_addr, from_port, from_seq, to_addr, to_port, to_seq, num, redundancy, stride, delay, inject); - return 0; + return 0; } diff --git a/auxil/zeek-aux/testing/Baseline/update-changes.replace-version-in-c-header/header.h b/auxil/zeek-aux/testing/Baseline/update-changes.replace-version-in-c-header/header.h index 7a160c5abb..4140d66d10 100644 --- a/auxil/zeek-aux/testing/Baseline/update-changes.replace-version-in-c-header/header.h +++ b/auxil/zeek-aux/testing/Baseline/update-changes.replace-version-in-c-header/header.h @@ -1,5 +1,5 @@ -### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -#define ZEEK_VERSION "1.0.0-2" /* with comment */ -#define ZEEK_VERSION "1.0.0-2" /* with comment */ - #define FOO_VERSION "1.0.0-2" // another comment -... +## #BTest baseline data generated by btest - diff.Do not edit.Use "btest -U/-u" to update.Requires BTest >= 0.63. +#define ZEEK_VERSION "1.0.0-2" /* with comment */ +#define ZEEK_VERSION "1.0.0-2" /* with comment */ +#define FOO_VERSION "1.0.0-2" // another comment + ... diff --git a/auxil/zeek-aux/zeek-archiver/zeek-archiver.cc b/auxil/zeek-aux/zeek-archiver/zeek-archiver.cc index be1e0e5e08..4fc379c1b2 100644 --- a/auxil/zeek-aux/zeek-archiver/zeek-archiver.cc +++ b/auxil/zeek-aux/zeek-archiver/zeek-archiver.cc @@ -1,870 +1,777 @@ -#define _XOPEN_SOURCE -#include +// See the file "COPYING" in the main distribution directory for copyright. -#include -#include -#include -#include -#include +#define _XOPEN_SOURCE #include #include - +#include +#include +#include +#include +#include +#include #include +#include +#include #include +#include #include #include -#include #include -#include #include -#include +#include +#include #include #include -#include #include -#include constexpr auto ZEEK_ARCHIVER_VERSION = "v0.50-174"; struct Options { - std::string src_dir; - std::string dst_dir; + std::string src_dir; + std::string dst_dir; - bool verbose = false; - bool oneshot = false; - std::string delimiter = "__"; - std::string compress_ext = "gz"; - std::string compress_cmd = "gzip"; - std::string timestamp_fmt = "%Y-%m-%d-%H-%M-%S"; - std::vector zip_file_extensions = { "gz", "bz2", "lz", "lz4" }; + bool verbose = false; + bool oneshot = false; + std::string delimiter = "__"; + std::string compress_ext = "gz"; + std::string compress_cmd = "gzip"; + std::string timestamp_fmt = "%Y-%m-%d-%H-%M-%S"; + std::vector zip_file_extensions = {"gz", "bz2", "lz", "lz4"}; - int idle_poll_interval = 30; + int idle_poll_interval = 30; }; static Options options; struct LogFile { - std::string path; - std::string name; - struct tm open; - struct tm close; - std::string ext; - std::string suffix; + std::string path; + std::string name; + struct tm open; + struct tm close; + std::string ext; + std::string suffix; - std::string DestDir() const - { - char buf[64]; - auto res = strftime(buf, sizeof(buf), "%Y-%m-%d", &open); + std::string DestDir() const { + char buf[64]; + auto res = strftime(buf, sizeof(buf), "%Y-%m-%d", &open); - if ( res == 0 ) - return {}; + if ( res == 0 ) + return {}; - return buf; - } + return buf; + } - std::string DestFile() const - { - constexpr auto time_fmt = "%H:%M:%S"; - char buf[64]; - auto res = strftime(buf, sizeof(buf), time_fmt, &open); + std::string DestFile() const { + constexpr auto time_fmt = "%H:%M:%S"; + char buf[64]; + auto res = strftime(buf, sizeof(buf), time_fmt, &open); - if ( res == 0 ) - return {}; + if ( res == 0 ) + return {}; - std::string start = buf; + std::string start = buf; - res = strftime(buf, sizeof(buf), time_fmt, &close); + res = strftime(buf, sizeof(buf), time_fmt, &close); - if ( res == 0 ) - return {}; + if ( res == 0 ) + return {}; - std::string close = buf; + std::string close = buf; - std::string r = name + "." + start + "-" + close; - if ( ! suffix.empty() ) - r += "-" + suffix; + std::string r = name + "." + start + "-" + close; + if ( ! suffix.empty() ) + r += "-" + suffix; - return r + ext; - } + return r + ext; + } }; -static double now() - { - struct timeval tv; - - if ( gettimeofday(&tv, 0) < 0 ) - return 0; - - return (double)tv.tv_sec + (double)tv.tv_usec / 1e6; - } - -static void debug(const char* format, ...) __attribute__((format (printf, 1, 2))); -static void debug(const char* format, ...) - { - if ( ! options.verbose ) - return; - - auto f = stdout; - fprintf(f, "[%17.06f] [DEBUG] ", now()); - - va_list args; - va_start(args, format); - vfprintf(f, format, args); - va_end(args); - - fprintf(f, "\n"); - } - -static void info(const char* format, ...) __attribute__((format (printf, 1, 2))); -static void info(const char* format, ...) - { - auto f = stdout; - fprintf(f, "[%17.06f] [INFO] ", now()); - - va_list args; - va_start(args, format); - vfprintf(f, format, args); - va_end(args); - - fprintf(f, "\n"); - } - -static void error(const char* format, ...) __attribute__((format (printf, 1, 2))); -static void error(const char* format, ...) - { - auto f = stderr; - fprintf(f, "[%17.06f] [ERROR] ", now()); - - va_list args; - va_start(args, format); - vfprintf(f, format, args); - va_end(args); - - fprintf(f, "\n"); - } - -static void fatal(const char* format, ...) __attribute__((format (printf, 1, 2))); -static void fatal(const char* format, ...) - { - auto f = stderr; - fprintf(f, "[%17.06f] [FATAL] ", now()); - - va_list args; - va_start(args, format); - vfprintf(f, format, args); - va_end(args); - - fprintf(f, "\n"); - exit(1); - } - -static void print_version(FILE* f) - { - fprintf(f, "zeek-archiver %s\n", ZEEK_ARCHIVER_VERSION); - } - -static void print_usage() - { - print_version(stderr); - fprintf(stderr, "usage: zeek-archiver [options] \n"); - fprintf(stderr, " | A directory to monitor for Zeek log files\n"); - fprintf(stderr, " | A directory to archive Zeek logs into\n"); - fprintf(stderr, " --version | Print version and exit\n"); - fprintf(stderr, " -1 | Archive current logs and exit w/o looping\n"); - fprintf(stderr, " -h|--help | Show this usage information\n"); - fprintf(stderr, " -v|--verbose | Print verbose/debug logs to stderr\n"); - fprintf(stderr, " -c|--compress | File extension and compression command,\n" - " empty string means \"disable compression\"\n" - " (default: \"gz,gzip\")\n"); - fprintf(stderr, " -d|--delimiter | Delimiter between timestamps in log names\n" - " (default: \"__\")\n"); - fprintf(stderr, " -t|--time-fmt | Format of timestamps within input file names\n" - " (default: \"%%Y-%%m-%%d-%%H-%%M-%%S\")\n"); - fprintf(stderr, " -z|--zip-extensions | File extensions for already-zipped logs,\n" - " an empty string disables this feature\n" - " (default: \"gz,bz2,lz,lz4\")\n"); - } - -static void usage_error(const char* format, ...) __attribute__((format (printf, 1, 2))); -static void usage_error(const char* format, ...) - { - print_usage(); - - fprintf(stderr, "ERROR: "); - - va_list args; - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - - fprintf(stderr, "\n"); - - exit(1); - } - -static std::vector -split_string(std::string_view input, std::string_view delim) - { - std::vector rval; - size_t pos = 0; - size_t n = 0; - - while ( (n = input.find(delim, pos)) != std::string::npos ) - { - rval.emplace_back(input.substr(pos, n - pos)); - pos = n + delim.size(); - } - - rval.emplace_back(input.substr(pos)); - return rval; - } - -static std::string strip_string(std::string s) - { - auto notspace = [](unsigned char c) - { - return ! std::isspace(c); - }; - s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace)); - s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end()); - return s; - } - -static void consume_option_value(const std::string& flag, std::string arg_value) - { - if ( flag == "-c" || flag == "--compress" ) - { - if ( arg_value.empty() ) - options.compress_cmd = ""; - else - { - auto parts = split_string(arg_value, ","); - - if ( parts.size() != 2 ) - usage_error("--compress must give a 'ext,compress_cmd' formatted " - "value, got: %s", arg_value.data()); - - options.compress_ext = parts[0]; - options.compress_cmd = parts[1]; - } - } - - - else if ( flag == "-d" || flag == "--delimiter" ) - { - if ( arg_value.empty() ) - usage_error("flag '%s' is missing a value", flag.data()); - - options.delimiter = std::move(arg_value); - } - - else if ( flag == "-t" || flag == "--time-fmt" ) - { - if ( arg_value.empty() ) - usage_error("flag '%s' is missing a value", flag.data()); - - options.timestamp_fmt = std::move(arg_value); - } - - else if ( flag == "-z" || flag == "--zip-extensions" ) - { - options.zip_file_extensions = split_string(arg_value, ","); - } - } - -static void parse_options(int argc, char** argv) - { - std::set flags = { - "--version", - "-1", - "-h", "--help", - "-v", "--verbose", - "-c", "--compress", - "-d", "--delimiter", - "-t", "--time-fmt", - "-z", "--zip-extensions", - }; - - bool in_options = true; - - for ( auto i = 1; i < argc; ++i ) - { - auto arg = argv[i]; - - if ( ! arg[0] ) - continue; - - if ( arg[0] == '-' ) - { - if ( ! in_options ) - usage_error("optional flags must precede non-optional arguments: " - "'%s'", arg); - - if ( ! arg[1] ) - // Has to be something after a '-' - usage_error("invalid argument: '%s'", arg); - - if ( arg[1] != '-' && arg[2] && arg[2] != '=' ) - // Invalid short flag: must be -x, -x v, or -x=v - usage_error("invalid argument: '%s'", arg); - - std::string flag = arg; - std::string opt_value; - - auto it = flag.find('='); - - if ( it == std::string::npos ) - { - if ( i + 1 < argc ) - opt_value = argv[i + 1]; - } - else - { - opt_value = flag.substr(it + 1); - flag = flag.substr(0, it); - } - - if ( flags.find(flag) == flags.end() ) - usage_error("invalid argument: '%s'", arg); - - if ( flag == "-1" ) - { - if ( ! opt_value.empty() && it != std::string::npos ) - usage_error("invalid argument=value: '%s'", arg); - - options.oneshot = true; - continue; - } - - if ( flag == "--version" ) - { - if ( ! opt_value.empty() && it != std::string::npos ) - usage_error("invalid argument=value: '%s'", arg); - - print_version(stdout); - exit(0); - } - - if ( flag == "-h" || flag == "--help" ) - { - if ( ! opt_value.empty() && it != std::string::npos ) - usage_error("invalid argument=value: '%s'", arg); - - print_usage(); - exit(0); - } - - if ( flag == "-v" || flag == "--verbose" ) - { - if ( ! opt_value.empty() && it != std::string::npos ) - usage_error("invalid argument=value: '%s'", arg); - - options.verbose = true; - continue; - } - - if ( it == std::string::npos ) - ++i; - - consume_option_value(flag, std::move(opt_value)); - continue; - } - else - { - if ( options.src_dir.empty() ) - { - in_options = false; - options.src_dir = arg; - } - else if ( options.dst_dir.empty() ) - { - in_options = false; - options.dst_dir = arg; - } - else - usage_error("extra/invalid argument: '%s': / " - "already provided: %s/%s", arg, - options.src_dir.data(), options.dst_dir.data()); - } - } - - if ( options.src_dir.empty() ) - usage_error("no provided"); - - if ( options.dst_dir.empty() ) - usage_error("no provided"); - } - -static bool make_dir(const char* dir) - { - if ( mkdir(dir, 0775) == 0 ) - return true; - - auto mkdir_errno = errno; - struct stat st; - - if ( stat(dir, &st) == -1 ) - { - // Show the original failure reason for mkdir() since nothing's there - // or we can't even tell what is now. - error("Failed to create directory %s: %s", dir, strerror(mkdir_errno)); - return false; - } - - if ( S_ISDIR(st.st_mode) ) - return true; - - error("Failed to create directory %s: exists but is not a directory", dir); - return false; - } - -static bool make_dirs(std::string_view dir) - { - auto parts = split_string(dir, "/"); - std::string current_dir = dir[0] == '/' ? "/" : ""; - std::vector dirs; - - for ( auto& p : parts ) - if ( ! p.empty() ) - dirs.emplace_back(std::move(p)); - - for ( size_t i = 0; i < dirs.size(); ++i ) - { - if ( i > 0 ) - current_dir += '/'; - - current_dir += dirs[i]; - - if ( ! make_dir(current_dir.data()) ) - return false; - } - - return true; - } - -bool is_file(const char* path) - { - struct stat st; - - if ( stat(path, &st) == -1 ) - { - if ( errno != ENOENT ) - error("can't stat %s: %s", path, strerror(errno)); - - return false; - } - - return S_ISREG(st.st_mode); - } - -std::optional same_filesystem(const char* path1, const char* path2) - { - struct stat st1; - struct stat st2; - - if ( stat(path1, &st1) == -1 ) - { - error("can't stat %s: %s", path1, strerror(errno)); - return {}; - } - - if ( stat(path2, &st2) == -1 ) - { - error("can't stat %s: %s", path2, strerror(errno)); - return {}; - } - - return st1.st_dev == st2.st_dev; - } - -static bool ends_with(std::string_view s, std::string_view ending) - { - if ( ending.size() > s.size() ) - return false; - - return std::equal(ending.rbegin(), ending.rend(), s.rbegin()); - } - -static bool already_zipped(std::string_view file) - { - for ( const auto& e : options.zip_file_extensions ) - if ( ends_with(file, e) ) - return true; - - return false; - } +static double now() { + struct timeval tv; + + if ( gettimeofday(&tv, 0) < 0 ) + return 0; + + return (double)tv.tv_sec + (double)tv.tv_usec / 1e6; +} + +static void debug(const char* format, ...) __attribute__((format(printf, 1, 2))); +static void debug(const char* format, ...) { + if ( ! options.verbose ) + return; + + auto f = stdout; + fprintf(f, "[%17.06f] [DEBUG] ", now()); + + va_list args; + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + + fprintf(f, "\n"); +} + +static void info(const char* format, ...) __attribute__((format(printf, 1, 2))); +static void info(const char* format, ...) { + auto f = stdout; + fprintf(f, "[%17.06f] [INFO] ", now()); + + va_list args; + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + + fprintf(f, "\n"); +} + +static void error(const char* format, ...) __attribute__((format(printf, 1, 2))); +static void error(const char* format, ...) { + auto f = stderr; + fprintf(f, "[%17.06f] [ERROR] ", now()); + + va_list args; + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + + fprintf(f, "\n"); +} + +static void fatal(const char* format, ...) __attribute__((format(printf, 1, 2))); +static void fatal(const char* format, ...) { + auto f = stderr; + fprintf(f, "[%17.06f] [FATAL] ", now()); + + va_list args; + va_start(args, format); + vfprintf(f, format, args); + va_end(args); + + fprintf(f, "\n"); + exit(1); +} + +static void print_version(FILE* f) { fprintf(f, "zeek-archiver %s\n", ZEEK_ARCHIVER_VERSION); } + +static void print_usage() { + print_version(stderr); + fprintf(stderr, "usage: zeek-archiver [options] \n"); + fprintf(stderr, " | A directory to monitor for Zeek log files\n"); + fprintf(stderr, " | A directory to archive Zeek logs into\n"); + fprintf(stderr, " --version | Print version and exit\n"); + fprintf(stderr, " -1 | Archive current logs and exit w/o looping\n"); + fprintf(stderr, " -h|--help | Show this usage information\n"); + fprintf(stderr, " -v|--verbose | Print verbose/debug logs to stderr\n"); + fprintf(stderr, + " -c|--compress | File extension and compression command,\n" + " empty string means \"disable compression\"\n" + " (default: \"gz,gzip\")\n"); + fprintf(stderr, + " -d|--delimiter | Delimiter between timestamps in log names\n" + " (default: \"__\")\n"); + fprintf(stderr, + " -t|--time-fmt | Format of timestamps within input file names\n" + " (default: \"%%Y-%%m-%%d-%%H-%%M-%%S\")\n"); + fprintf(stderr, + " -z|--zip-extensions | File extensions for already-zipped logs,\n" + " an empty string disables this feature\n" + " (default: \"gz,bz2,lz,lz4\")\n"); +} + +static void usage_error(const char* format, ...) __attribute__((format(printf, 1, 2))); +static void usage_error(const char* format, ...) { + print_usage(); + + fprintf(stderr, "ERROR: "); + + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + fprintf(stderr, "\n"); + + exit(1); +} + +static std::vector split_string(std::string_view input, std::string_view delim) { + std::vector rval; + size_t pos = 0; + size_t n = 0; + + while ( (n = input.find(delim, pos)) != std::string::npos ) { + rval.emplace_back(input.substr(pos, n - pos)); + pos = n + delim.size(); + } + + rval.emplace_back(input.substr(pos)); + return rval; +} + +static std::string strip_string(std::string s) { + auto notspace = [](unsigned char c) { return ! std::isspace(c); }; + s.erase(s.begin(), std::find_if(s.begin(), s.end(), notspace)); + s.erase(std::find_if(s.rbegin(), s.rend(), notspace).base(), s.end()); + return s; +} + +static void consume_option_value(const std::string& flag, std::string arg_value) { + if ( flag == "-c" || flag == "--compress" ) { + if ( arg_value.empty() ) + options.compress_cmd = ""; + else { + auto parts = split_string(arg_value, ","); + + if ( parts.size() != 2 ) + usage_error( + "--compress must give a 'ext,compress_cmd' formatted " + "value, got: %s", + arg_value.data()); + + options.compress_ext = parts[0]; + options.compress_cmd = parts[1]; + } + } + + + else if ( flag == "-d" || flag == "--delimiter" ) { + if ( arg_value.empty() ) + usage_error("flag '%s' is missing a value", flag.data()); + + options.delimiter = std::move(arg_value); + } + + else if ( flag == "-t" || flag == "--time-fmt" ) { + if ( arg_value.empty() ) + usage_error("flag '%s' is missing a value", flag.data()); + + options.timestamp_fmt = std::move(arg_value); + } + + else if ( flag == "-z" || flag == "--zip-extensions" ) { + options.zip_file_extensions = split_string(arg_value, ","); + } +} + +static void parse_options(int argc, char** argv) { + std::set flags = { + "--version", "-1", "-h", "--help", "-v", "--verbose", "-c", + "--compress", "-d", "--delimiter", "-t", "--time-fmt", "-z", "--zip-extensions", + }; + + bool in_options = true; + + for ( auto i = 1; i < argc; ++i ) { + auto arg = argv[i]; + + if ( ! arg[0] ) + continue; + + if ( arg[0] == '-' ) { + if ( ! in_options ) + usage_error( + "optional flags must precede non-optional arguments: " + "'%s'", + arg); + + if ( ! arg[1] ) + // Has to be something after a '-' + usage_error("invalid argument: '%s'", arg); + + if ( arg[1] != '-' && arg[2] && arg[2] != '=' ) + // Invalid short flag: must be -x, -x v, or -x=v + usage_error("invalid argument: '%s'", arg); + + std::string flag = arg; + std::string opt_value; + + auto it = flag.find('='); + + if ( it == std::string::npos ) { + if ( i + 1 < argc ) + opt_value = argv[i + 1]; + } + else { + opt_value = flag.substr(it + 1); + flag = flag.substr(0, it); + } + + if ( flags.find(flag) == flags.end() ) + usage_error("invalid argument: '%s'", arg); + + if ( flag == "-1" ) { + if ( ! opt_value.empty() && it != std::string::npos ) + usage_error("invalid argument=value: '%s'", arg); + + options.oneshot = true; + continue; + } + + if ( flag == "--version" ) { + if ( ! opt_value.empty() && it != std::string::npos ) + usage_error("invalid argument=value: '%s'", arg); + + print_version(stdout); + exit(0); + } + + if ( flag == "-h" || flag == "--help" ) { + if ( ! opt_value.empty() && it != std::string::npos ) + usage_error("invalid argument=value: '%s'", arg); + + print_usage(); + exit(0); + } + + if ( flag == "-v" || flag == "--verbose" ) { + if ( ! opt_value.empty() && it != std::string::npos ) + usage_error("invalid argument=value: '%s'", arg); + + options.verbose = true; + continue; + } + + if ( it == std::string::npos ) + ++i; + + consume_option_value(flag, std::move(opt_value)); + continue; + } + else { + if ( options.src_dir.empty() ) { + in_options = false; + options.src_dir = arg; + } + else if ( options.dst_dir.empty() ) { + in_options = false; + options.dst_dir = arg; + } + else + usage_error( + "extra/invalid argument: '%s': / " + "already provided: %s/%s", + arg, options.src_dir.data(), options.dst_dir.data()); + } + } + + if ( options.src_dir.empty() ) + usage_error("no provided"); + + if ( options.dst_dir.empty() ) + usage_error("no provided"); +} + +static bool make_dir(const char* dir) { + if ( mkdir(dir, 0775) == 0 ) + return true; + + auto mkdir_errno = errno; + struct stat st; + + if ( stat(dir, &st) == -1 ) { + // Show the original failure reason for mkdir() since nothing's there + // or we can't even tell what is now. + error("Failed to create directory %s: %s", dir, strerror(mkdir_errno)); + return false; + } + + if ( S_ISDIR(st.st_mode) ) + return true; + + error("Failed to create directory %s: exists but is not a directory", dir); + return false; +} + +static bool make_dirs(std::string_view dir) { + auto parts = split_string(dir, "/"); + std::string current_dir = dir[0] == '/' ? "/" : ""; + std::vector dirs; + + for ( auto& p : parts ) + if ( ! p.empty() ) + dirs.emplace_back(std::move(p)); + + for ( size_t i = 0; i < dirs.size(); ++i ) { + if ( i > 0 ) + current_dir += '/'; + + current_dir += dirs[i]; + + if ( ! make_dir(current_dir.data()) ) + return false; + } + + return true; +} + +bool is_file(const char* path) { + struct stat st; + + if ( stat(path, &st) == -1 ) { + if ( errno != ENOENT ) + error("can't stat %s: %s", path, strerror(errno)); + + return false; + } + + return S_ISREG(st.st_mode); +} + +std::optional same_filesystem(const char* path1, const char* path2) { + struct stat st1; + struct stat st2; + + if ( stat(path1, &st1) == -1 ) { + error("can't stat %s: %s", path1, strerror(errno)); + return {}; + } + + if ( stat(path2, &st2) == -1 ) { + error("can't stat %s: %s", path2, strerror(errno)); + return {}; + } + + return st1.st_dev == st2.st_dev; +} + +static bool ends_with(std::string_view s, std::string_view ending) { + if ( ending.size() > s.size() ) + return false; + + return std::equal(ending.rbegin(), ending.rend(), s.rbegin()); +} + +static bool already_zipped(std::string_view file) { + for ( const auto& e : options.zip_file_extensions ) + if ( ends_with(file, e) ) + return true; + + return false; +} static pid_t child_pid = -1; -static void signal_handler(int signal) - { - if ( child_pid > 0 ) - { - kill(child_pid, SIGKILL); - int status; - waitpid(child_pid, &status, 0); - } +static void signal_handler(int signal) { + if ( child_pid > 0 ) { + kill(child_pid, SIGKILL); + int status; + waitpid(child_pid, &status, 0); + } - _exit(131); - } + _exit(131); +} // Fork a child and associate its stdin/stdout with the src and dst files, // then run compress_cmd via system(). -static int run_compress_cmd(const char* src_file, const char* dst_file) - { - child_pid = fork(); - - if ( child_pid == -1 ) - { - error("Failed to fork() to run compress command: %s", strerror(errno)); - return -1; - } - - if ( child_pid == 0 ) - { - int src_fd = open(src_file, O_RDONLY); - - if ( src_fd < 0 ) - { - error("Failed to open src_file %s: %s", src_file, strerror(errno)); - exit(254); - } - - if ( dup2(src_fd, STDIN_FILENO) == -1 ) - { - error("Failed to redirect src_file %s to stdin: %s", src_file, - strerror(errno)); - exit(253); - } - - if ( src_fd != STDIN_FILENO ) - close(src_fd); - - int dst_fd = open(dst_file, O_CREAT | O_TRUNC | O_WRONLY, 0664); - - if ( dst_fd < 0 ) - { - error("Failed to open dst_file %s: %s", dst_file, strerror(errno)); - exit(252); - } - - if ( dup2(dst_fd, STDOUT_FILENO) == -1 ) - { - error("Failed to redirect dst_file %s to stdout: %s", dst_file, - strerror(errno)); - exit(251); - } - - if ( dst_fd != STDOUT_FILENO ) - close(dst_fd); - - // Call the compression program via the shell. - execlp("sh", "sh", "-c", options.compress_cmd.data(), (char*)0); - error("Failed to exec(): %s", strerror(errno)); - exit(255); - } - - int status; - waitpid(child_pid, &status, 0); - child_pid = -1; - - if ( ! (WIFEXITED(status) && WEXITSTATUS(status) == 0) ) - { - if ( WIFEXITED(status) ) - error("Compression of %s failed, command exit status: %d (0x%x)", - src_file, WEXITSTATUS(status), status); - else if ( WIFSIGNALED(status) ) - error("Compression of %s failed, got signal: %d (0x%x)", - src_file, WTERMSIG(status), status); - else - error("Compression of %s failed, unknown reason/status: (0x%x)", - src_file, status); - - // If the compression command failed, unlink the destination - // file. Ignore any errors - it may not have been created. - unlink(dst_file); - } - - return WIFEXITED(status) ? WEXITSTATUS(status) : -1; - } - -static int archive_logs() - { - int rval = 0; - - auto d = opendir(options.src_dir.data()); - - if ( ! d ) - { - debug("Source directory '%s', does not exist", options.src_dir.data()); - return rval; - } - - struct dirent* dp; - std::vector log_files; - - while ( (dp = readdir(d)) ) - { - if ( dp->d_name[0] == '.' ) - continue; - - std::string path = options.src_dir + "/" + dp->d_name; - - if ( ! is_file(path.data()) ) - { - debug("Skipping archival of non-file: %s", dp->d_name); - continue; - } - - // Default log file format either has 4 parts delimited by "__", - // as follows: - // - // test__2020-07-16-09-43-10__2020-07-16-09-43-10__.log - // - // Or, 5 parts delimited by "__" where the part before the extension - // is a generic comma separated key=value construct: - // - // test__2020-07-16-09-43-10__2020-07-16-09-43-10__log_suffix=logger-1,pid=4711__.log - // - // The comma character is reasonable to work with on a shell and assumed - // to not be of importance for metadata values. If this seems over-engineered, - // maybe, but adding a plain positional parameter with an implied meaning also - // adds a required parameter for any future extensions and we currently don't - // have a side-channel to propagate additional information. - // - auto parts = split_string(dp->d_name, options.delimiter); - - if ( parts.size() != 4 && parts.size() != 5) - { - debug("Skipping archival of non-log: %s", dp->d_name); - continue; - } - - LogFile lf; - lf.path = path; - lf.name = parts[0]; - - auto res = strptime(parts[1].data(), options.timestamp_fmt.data(), &lf.open); - - if ( ! res ) - { - debug("Skipping archival of log with bad timestamp format: %s", dp->d_name); - continue; - } - - if ( res != parts[1].data() + parts[1].size() ) - debug("Possible log with timestamp format mismatch: %s", dp->d_name); - - res = strptime(parts[2].data(), options.timestamp_fmt.data(), &lf.close); - - if ( ! res ) - { - debug("Skipping archival of log with bad timestamp format: %s", dp->d_name); - continue; - } - - if ( res != parts[2].data() + parts[2].size() ) - debug("Possible log with timestamp format mismatch: %s", dp->d_name); - - if ( parts.size() == 4 ) - lf.ext = parts[3]; - else - { - lf.ext = parts[4]; - - bool metadata_error = false; - - // split_string() returns a single entry for - // an empty string, avoid that scenario. - std::vector metadata_parts; - if ( ! parts[3].empty() ) - metadata_parts = split_string(parts[3], ","); - - for (const auto& entry : metadata_parts) - { - auto key_value = split_string(entry, "="); - if ( key_value.size() != 2 ) - { - metadata_error = true; - break; - } - - auto key = strip_string(key_value[0]); - auto value = strip_string(key_value[1]); - if ( key.empty() || value.empty() ) - { - metadata_error = true; - break; - } - - // Only log_suffix is understood as metadata. - if ( key == "log_suffix" ) - { - debug("Using log_suffix '%s'", value.data()); - lf.suffix = value; - } - else - debug("Ignoring unknown metadata entry %s in %s", key.data(), dp->d_name); - - } - - if ( metadata_error ) - { - debug("Skipping archival of log with bad metadata format: %s", dp->d_name); - continue; - } - } - - log_files.emplace_back(std::move(lf)); - } - - closedir(d); - - for ( const auto& lf : log_files ) - { - auto dst_dir = options.dst_dir + "/" + lf.DestDir(); - auto dst_file = dst_dir + "/" + lf.DestFile(); - auto tmp_file = dst_dir + "/.tmp." + lf.DestFile(); - const auto& src_file = lf.path; - - if ( ! make_dirs(dst_dir) ) - { - error("Skipped archiving %s: failed to create dir %s", - src_file.data(), dst_dir.data()); - continue; - } - - bool compress = ! options.compress_cmd.empty() && ! already_zipped(lf.ext); - - if ( compress ) - { - if ( ! options.compress_ext.empty() ) - dst_file += "." + options.compress_ext; - - debug("Archive via compression: %s -> %s", src_file.data(), dst_file.data()); - auto res = run_compress_cmd(src_file.data(), tmp_file.data()); - - if ( res != 0 ) - continue; - - res = rename(tmp_file.data(), dst_file.data()); - - if ( res == -1 ) - { - error("Failed to rename %s -> %s: %s", - tmp_file.data(), dst_file.data(), strerror(errno)); - continue; - } - - ++rval; - res = unlink(src_file.data()); - - if ( res == -1 ) - error("Failed to unlink %s; %s", src_file.data(), strerror(errno)); - - continue; - } - - auto same_fs = same_filesystem(src_file.data(), dst_dir.data()); - - if ( ! same_fs ) - { - error("Failed to compare filesystems of %s and %s", - src_file.data(), dst_dir.data()); - continue; - } - - if ( *same_fs ) - { - debug("Archive via rename: %s -> %s", src_file.data(), dst_file.data()); - auto res = rename(src_file.data(), dst_file.data()); - - if ( res == -1 ) - error("Failed to rename %s -> %s: %s", - src_file.data(), dst_file.data(), strerror(errno)); - else - ++rval; - } - else - { - debug("Archive via copy: %s -> %s", src_file.data(), dst_file.data()); - - std::ifstream src; - std::ofstream dst; - src.exceptions(std::ifstream::failbit | std::ifstream::badbit); - dst.exceptions(std::ofstream::failbit | std::ofstream::badbit); - - try - { - src.open(src_file, std::ios::binary); - dst.open(tmp_file, std::ios::binary); - dst << src.rdbuf(); - } - catch ( const std::system_error& e ) - { - error("Failed to copy %s to temporary file %s: %s", - src_file.data(), tmp_file.data(), e.code().message().data()); - continue; - } - - auto res = rename(tmp_file.data(), dst_file.data()); - - if ( res == -1 ) - { - error("Failed to rename %s -> %s: %s", - tmp_file.data(), dst_file.data(), strerror(errno)); - continue; - } - - ++rval; - res = unlink(src_file.data()); - - if ( res == -1 ) - error("Failed to unlink %s; %s", src_file.data(), strerror(errno)); - } - } - - return rval; - } - -int main(int argc, char** argv) - { - signal(SIGTERM, signal_handler); - parse_options(argc, argv); - - debug("Using src_dir: '%s'", options.src_dir.data()); - debug("Using dst_dir: '%s'", options.dst_dir.data()); - debug("Using oneshot option: '%d'", options.oneshot); - debug("Using delimiter option: '%s'", options.delimiter.data()); - debug("Using timestamp format option: '%s'", options.timestamp_fmt.data()); - debug("Using compression extension option: '%s'", options.compress_ext.data()); - debug("Using compression command option: '%s'", options.compress_cmd.data()); - debug("Using poll interval: '%d'", options.idle_poll_interval); - - for ( const auto& e : options.zip_file_extensions ) - debug("Using zip-extension option: '%s'", e.data()); - - if ( ! make_dirs(options.dst_dir) ) - fatal("Failed to create destination archive dir: %s", options.dst_dir.data()); - - for ( ; ; ) - { - using hrc = std::chrono::high_resolution_clock; - auto t0 = hrc::now(); - auto num_archived = archive_logs(); - auto t1 = hrc::now(); - - if ( num_archived > 0 ) - { - auto dt = std::chrono::duration(t1 - t0).count(); - info("Archived %d logs in %f seconds", num_archived, dt); - } - - if ( options.oneshot ) - break; - - sleep(num_archived > 0 ? 1 : options.idle_poll_interval); - } - - return 0; - } +static int run_compress_cmd(const char* src_file, const char* dst_file) { + child_pid = fork(); + + if ( child_pid == -1 ) { + error("Failed to fork() to run compress command: %s", strerror(errno)); + return -1; + } + + if ( child_pid == 0 ) { + int src_fd = open(src_file, O_RDONLY); + + if ( src_fd < 0 ) { + error("Failed to open src_file %s: %s", src_file, strerror(errno)); + exit(254); + } + + if ( dup2(src_fd, STDIN_FILENO) == -1 ) { + error("Failed to redirect src_file %s to stdin: %s", src_file, strerror(errno)); + exit(253); + } + + if ( src_fd != STDIN_FILENO ) + close(src_fd); + + int dst_fd = open(dst_file, O_CREAT | O_TRUNC | O_WRONLY, 0664); + + if ( dst_fd < 0 ) { + error("Failed to open dst_file %s: %s", dst_file, strerror(errno)); + exit(252); + } + + if ( dup2(dst_fd, STDOUT_FILENO) == -1 ) { + error("Failed to redirect dst_file %s to stdout: %s", dst_file, strerror(errno)); + exit(251); + } + + if ( dst_fd != STDOUT_FILENO ) + close(dst_fd); + + // Call the compression program via the shell. + execlp("sh", "sh", "-c", options.compress_cmd.data(), (char*)0); + error("Failed to exec(): %s", strerror(errno)); + exit(255); + } + + int status; + waitpid(child_pid, &status, 0); + child_pid = -1; + + if ( ! (WIFEXITED(status) && WEXITSTATUS(status) == 0) ) { + if ( WIFEXITED(status) ) + error("Compression of %s failed, command exit status: %d (0x%x)", src_file, WEXITSTATUS(status), status); + else if ( WIFSIGNALED(status) ) + error("Compression of %s failed, got signal: %d (0x%x)", src_file, WTERMSIG(status), status); + else + error("Compression of %s failed, unknown reason/status: (0x%x)", src_file, status); + + // If the compression command failed, unlink the destination + // file. Ignore any errors - it may not have been created. + unlink(dst_file); + } + + return WIFEXITED(status) ? WEXITSTATUS(status) : -1; +} + +static int archive_logs() { + int rval = 0; + + auto d = opendir(options.src_dir.data()); + + if ( ! d ) { + debug("Source directory '%s', does not exist", options.src_dir.data()); + return rval; + } + + struct dirent* dp; + std::vector log_files; + + while ( (dp = readdir(d)) ) { + if ( dp->d_name[0] == '.' ) + continue; + + std::string path = options.src_dir + "/" + dp->d_name; + + if ( ! is_file(path.data()) ) { + debug("Skipping archival of non-file: %s", dp->d_name); + continue; + } + + // Default log file format either has 4 parts delimited by "__", + // as follows: + // + // test__2020-07-16-09-43-10__2020-07-16-09-43-10__.log + // + // Or, 5 parts delimited by "__" where the part before the extension + // is a generic comma separated key=value construct: + // + // test__2020-07-16-09-43-10__2020-07-16-09-43-10__log_suffix=logger-1,pid=4711__.log + // + // The comma character is reasonable to work with on a shell and assumed + // to not be of importance for metadata values. If this seems over-engineered, + // maybe, but adding a plain positional parameter with an implied meaning also + // adds a required parameter for any future extensions and we currently don't + // have a side-channel to propagate additional information. + // + auto parts = split_string(dp->d_name, options.delimiter); + + if ( parts.size() != 4 && parts.size() != 5 ) { + debug("Skipping archival of non-log: %s", dp->d_name); + continue; + } + + LogFile lf; + lf.path = path; + lf.name = parts[0]; + + auto res = strptime(parts[1].data(), options.timestamp_fmt.data(), &lf.open); + + if ( ! res ) { + debug("Skipping archival of log with bad timestamp format: %s", dp->d_name); + continue; + } + + if ( res != parts[1].data() + parts[1].size() ) + debug("Possible log with timestamp format mismatch: %s", dp->d_name); + + res = strptime(parts[2].data(), options.timestamp_fmt.data(), &lf.close); + + if ( ! res ) { + debug("Skipping archival of log with bad timestamp format: %s", dp->d_name); + continue; + } + + if ( res != parts[2].data() + parts[2].size() ) + debug("Possible log with timestamp format mismatch: %s", dp->d_name); + + if ( parts.size() == 4 ) + lf.ext = parts[3]; + else { + lf.ext = parts[4]; + + bool metadata_error = false; + + // split_string() returns a single entry for + // an empty string, avoid that scenario. + std::vector metadata_parts; + if ( ! parts[3].empty() ) + metadata_parts = split_string(parts[3], ","); + + for ( const auto& entry : metadata_parts ) { + auto key_value = split_string(entry, "="); + if ( key_value.size() != 2 ) { + metadata_error = true; + break; + } + + auto key = strip_string(key_value[0]); + auto value = strip_string(key_value[1]); + if ( key.empty() || value.empty() ) { + metadata_error = true; + break; + } + + // Only log_suffix is understood as metadata. + if ( key == "log_suffix" ) { + debug("Using log_suffix '%s'", value.data()); + lf.suffix = value; + } + else + debug("Ignoring unknown metadata entry %s in %s", key.data(), dp->d_name); + } + + if ( metadata_error ) { + debug("Skipping archival of log with bad metadata format: %s", dp->d_name); + continue; + } + } + + log_files.emplace_back(std::move(lf)); + } + + closedir(d); + + for ( const auto& lf : log_files ) { + auto dst_dir = options.dst_dir + "/" + lf.DestDir(); + auto dst_file = dst_dir + "/" + lf.DestFile(); + auto tmp_file = dst_dir + "/.tmp." + lf.DestFile(); + const auto& src_file = lf.path; + + if ( ! make_dirs(dst_dir) ) { + error("Skipped archiving %s: failed to create dir %s", src_file.data(), dst_dir.data()); + continue; + } + + bool compress = ! options.compress_cmd.empty() && ! already_zipped(lf.ext); + + if ( compress ) { + if ( ! options.compress_ext.empty() ) + dst_file += "." + options.compress_ext; + + debug("Archive via compression: %s -> %s", src_file.data(), dst_file.data()); + auto res = run_compress_cmd(src_file.data(), tmp_file.data()); + + if ( res != 0 ) + continue; + + res = rename(tmp_file.data(), dst_file.data()); + + if ( res == -1 ) { + error("Failed to rename %s -> %s: %s", tmp_file.data(), dst_file.data(), strerror(errno)); + continue; + } + + ++rval; + res = unlink(src_file.data()); + + if ( res == -1 ) + error("Failed to unlink %s; %s", src_file.data(), strerror(errno)); + + continue; + } + + auto same_fs = same_filesystem(src_file.data(), dst_dir.data()); + + if ( ! same_fs ) { + error("Failed to compare filesystems of %s and %s", src_file.data(), dst_dir.data()); + continue; + } + + if ( *same_fs ) { + debug("Archive via rename: %s -> %s", src_file.data(), dst_file.data()); + auto res = rename(src_file.data(), dst_file.data()); + + if ( res == -1 ) + error("Failed to rename %s -> %s: %s", src_file.data(), dst_file.data(), strerror(errno)); + else + ++rval; + } + else { + debug("Archive via copy: %s -> %s", src_file.data(), dst_file.data()); + + std::ifstream src; + std::ofstream dst; + src.exceptions(std::ifstream::failbit | std::ifstream::badbit); + dst.exceptions(std::ofstream::failbit | std::ofstream::badbit); + + try { + src.open(src_file, std::ios::binary); + dst.open(tmp_file, std::ios::binary); + dst << src.rdbuf(); + } catch ( const std::system_error& e ) { + error("Failed to copy %s to temporary file %s: %s", src_file.data(), tmp_file.data(), + e.code().message().data()); + continue; + } + + auto res = rename(tmp_file.data(), dst_file.data()); + + if ( res == -1 ) { + error("Failed to rename %s -> %s: %s", tmp_file.data(), dst_file.data(), strerror(errno)); + continue; + } + + ++rval; + res = unlink(src_file.data()); + + if ( res == -1 ) + error("Failed to unlink %s; %s", src_file.data(), strerror(errno)); + } + } + + return rval; +} + +int main(int argc, char** argv) { + signal(SIGTERM, signal_handler); + parse_options(argc, argv); + + debug("Using src_dir: '%s'", options.src_dir.data()); + debug("Using dst_dir: '%s'", options.dst_dir.data()); + debug("Using oneshot option: '%d'", options.oneshot); + debug("Using delimiter option: '%s'", options.delimiter.data()); + debug("Using timestamp format option: '%s'", options.timestamp_fmt.data()); + debug("Using compression extension option: '%s'", options.compress_ext.data()); + debug("Using compression command option: '%s'", options.compress_cmd.data()); + debug("Using poll interval: '%d'", options.idle_poll_interval); + + for ( const auto& e : options.zip_file_extensions ) + debug("Using zip-extension option: '%s'", e.data()); + + if ( ! make_dirs(options.dst_dir) ) + fatal("Failed to create destination archive dir: %s", options.dst_dir.data()); + + for ( ;; ) { + using hrc = std::chrono::high_resolution_clock; + auto t0 = hrc::now(); + auto num_archived = archive_logs(); + auto t1 = hrc::now(); + + if ( num_archived > 0 ) { + auto dt = std::chrono::duration(t1 - t0).count(); + info("Archived %d logs in %f seconds", num_archived, dt); + } + + if ( options.oneshot ) + break; + + sleep(num_archived > 0 ? 1 : options.idle_poll_interval); + } + + return 0; +} diff --git a/auxil/zeek-aux/zeek-cut/zeek-cut.c b/auxil/zeek-aux/zeek-cut/zeek-cut.c index 9745f17029..9822816842 100644 --- a/auxil/zeek-aux/zeek-cut/zeek-cut.c +++ b/auxil/zeek-aux/zeek-cut/zeek-cut.c @@ -1,42 +1,42 @@ // See the file "COPYING" in the main distribution directory for copyright. -#include -#include #include +#include +#include // define required for FreeBSD #define _WITH_GETLINE #include #include -#include #include +#include /* The maximum length of converted timestamp that zeek-cut can handle. */ #define MAX_TIMESTAMP_LEN 100 /* User-specified options that stay constant during a run of zeek-cut. */ struct useropts { - int showhdr; /* show log headers? (0=no, 1=only first, 2=all) */ - int minimalview; /* show headers in minimal view? (0=no, 1=yes) */ - int negate; /* show all but the specified columns? (0=no, 1=yes) */ - int timeconv; /* do time conversion? (0=no, 1=local, 2=UTC) */ - char **columns; /* array of user-specified column names */ - int num_columns; /* number of user-specified column names */ - const char *ofs; /* user-specified output field separator character */ - const char *timefmt; /* strftime format string for time conversion */ + int showhdr; /* show log headers? (0=no, 1=only first, 2=all) */ + int minimalview; /* show headers in minimal view? (0=no, 1=yes) */ + int negate; /* show all but the specified columns? (0=no, 1=yes) */ + int timeconv; /* do time conversion? (0=no, 1=local, 2=UTC) */ + char** columns; /* array of user-specified column names */ + int num_columns; /* number of user-specified column names */ + const char* ofs; /* user-specified output field separator character */ + const char* timefmt; /* strftime format string for time conversion */ }; /* Parameters that might change with each log file being processed. */ struct logparams { - int *out_indexes; /* array of log file column indices to output */ - int num_out_indexes; /* number of elements in "out_indexes" */ - int idx_range; /* max. value in "out_indexes" plus one */ - int *time_cols; /* array of columns (0=not timestamp, 1=timestamp) */ - char **tmp_fields; /* array of pointers to each field on a line */ - int num_fields; /* number of fields in log file */ - char ifs[2]; /* input field separator character */ - char ofs[2]; /* output field separator character */ - char *unsetf; /* unset field string */ - long prev_ts; /* previous timestamp */ + int* out_indexes; /* array of log file column indices to output */ + int num_out_indexes; /* number of elements in "out_indexes" */ + int idx_range; /* max. value in "out_indexes" plus one */ + int* time_cols; /* array of columns (0=not timestamp, 1=timestamp) */ + char** tmp_fields; /* array of pointers to each field on a line */ + int num_fields; /* number of fields in log file */ + char ifs[2]; /* input field separator character */ + char ofs[2]; /* output field separator character */ + char* unsetf; /* unset field string */ + long prev_ts; /* previous timestamp */ }; @@ -65,10 +65,10 @@ int usage(void) { /* Return the index in "haystack" where "needle" is located (or -1 if not * found). */ -int string_index(char *haystack[], int haystack_size, const char *needle) { +int string_index(char* haystack[], int haystack_size, const char* needle) { int i; - for (i = 0; i < haystack_size; ++i) { - if (!strcmp(haystack[i], needle)) { + for ( i = 0; i < haystack_size; ++i ) { + if ( ! strcmp(haystack[i], needle) ) { return i; } } @@ -76,13 +76,14 @@ int string_index(char *haystack[], int haystack_size, const char *needle) { } /* Return the input field separator from the log's "#separator " header line. */ -char parsesep(const char *sepstr) { +char parsesep(const char* sepstr) { char ifs; - if (!strncmp(sepstr, "\\x", 2)) { + if ( ! strncmp(sepstr, "\\x", 2) ) { long sepval = strtol(sepstr + 2, NULL, 16); ifs = sepval; - } else { + } + else { ifs = sepstr[0]; } @@ -92,30 +93,30 @@ char parsesep(const char *sepstr) { /* Determine the columns (if any) where the field is "time". Return 0 for * success, and non-zero otherwise. */ -int find_timecol(const char *line, struct logparams *lp) { +int find_timecol(const char* line, struct logparams* lp) { int i; - int *tmpptr; - char *copy_of_line; - char *field_ptr; - char *field; + int* tmpptr; + char* copy_of_line; + char* field_ptr; + char* field; - tmpptr = (int *) realloc(lp->time_cols, lp->idx_range * sizeof(int)); - if (tmpptr == NULL) { + tmpptr = (int*)realloc(lp->time_cols, lp->idx_range * sizeof(int)); + if ( tmpptr == NULL ) { fputs("zeek-cut: out of memory\n", stderr); return 1; } lp->time_cols = tmpptr; - if ((copy_of_line = strdup(line)) == NULL) { + if ( (copy_of_line = strdup(line)) == NULL ) { fputs("zeek-cut: out of memory\n", stderr); return 1; } field_ptr = copy_of_line; int ret = 0; - for (i = 0; i < lp->idx_range; ++i) { - if ((field = strsep(&field_ptr, lp->ifs)) == NULL) { + for ( i = 0; i < lp->idx_range; ++i ) { + if ( (field = strsep(&field_ptr, lp->ifs)) == NULL ) { fputs("zeek-cut: log header does not have enough fields\n", stderr); ret = 1; break; @@ -135,38 +136,38 @@ int find_timecol(const char *line, struct logparams *lp) { * store in "idx_range" the maximum value contained in "out_indexes" plus one. * Return 0 for success, and non-zero otherwise. */ -int find_output_indexes(char *line, struct logparams *lp, struct useropts *bopts) { +int find_output_indexes(char* line, struct logparams* lp, struct useropts* bopts) { int idx; - int *out_indexes; - char *field_ptr; - char *copy_of_line = NULL; - char *field; + int* out_indexes; + char* field_ptr; + char* copy_of_line = NULL; + char* field; /* Get the number of fields */ lp->num_fields = 0; field = line; - while ((field = strchr(field, lp->ifs[0])) != NULL) { + while ( (field = strchr(field, lp->ifs[0])) != NULL ) { lp->num_fields++; field++; } lp->num_fields++; - char **tmpptr; + char** tmpptr; /* note: size is num_fields+1 because header lines have an extra field */ - tmpptr = (char **) realloc(lp->tmp_fields, (lp->num_fields + 1) * sizeof(char *)); - if (tmpptr == NULL) { + tmpptr = (char**)realloc(lp->tmp_fields, (lp->num_fields + 1) * sizeof(char*)); + if ( tmpptr == NULL ) { return 1; } lp->tmp_fields = tmpptr; - if (bopts->num_columns == 0) { + if ( bopts->num_columns == 0 ) { /* No columns specified on cmd-line, so use all the columns */ - out_indexes = (int *) realloc(lp->out_indexes, lp->num_fields * sizeof(int)); - if (out_indexes == NULL) { + out_indexes = (int*)realloc(lp->out_indexes, lp->num_fields * sizeof(int)); + if ( out_indexes == NULL ) { return 1; } - for (idx = 0; idx < lp->num_fields; ++idx) { + for ( idx = 0; idx < lp->num_fields; ++idx ) { out_indexes[idx] = idx; } @@ -177,44 +178,45 @@ int find_output_indexes(char *line, struct logparams *lp, struct useropts *bopts } /* Set tmp_fields to point to each field on the line */ - if ((copy_of_line = strdup(line)) == NULL) { + if ( (copy_of_line = strdup(line)) == NULL ) { return 1; } field_ptr = copy_of_line; idx = 0; - while ((field = strsep(&field_ptr, lp->ifs)) != NULL) { + while ( (field = strsep(&field_ptr, lp->ifs)) != NULL ) { lp->tmp_fields[idx++] = field; } int out_idx = 0; int maxval = 0; - if (!bopts->negate) { + if ( ! bopts->negate ) { /* One or more column names were specified on cmd-line */ - out_indexes = (int *) realloc(lp->out_indexes, bopts->num_columns * sizeof(int)); - if (out_indexes == NULL) { + out_indexes = (int*)realloc(lp->out_indexes, bopts->num_columns * sizeof(int)); + if ( out_indexes == NULL ) { return 1; } - for (idx = 0; idx < bopts->num_columns; ++idx) { + for ( idx = 0; idx < bopts->num_columns; ++idx ) { out_indexes[idx] = string_index(lp->tmp_fields, lp->num_fields, bopts->columns[idx]); - if (out_indexes[idx] > maxval) { + if ( out_indexes[idx] > maxval ) { maxval = out_indexes[idx]; } } out_idx = bopts->num_columns; - } else { + } + else { /* The "-n" option was specified on cmd-line */ - out_indexes = (int *) realloc(lp->out_indexes, lp->num_fields * sizeof(int)); - if (out_indexes == NULL) { + out_indexes = (int*)realloc(lp->out_indexes, lp->num_fields * sizeof(int)); + if ( out_indexes == NULL ) { return 1; } - for (idx = 0; idx < lp->num_fields; ++idx) { - if (string_index(bopts->columns, bopts->num_columns, lp->tmp_fields[idx]) == -1) { + for ( idx = 0; idx < lp->num_fields; ++idx ) { + if ( string_index(bopts->columns, bopts->num_columns, lp->tmp_fields[idx]) == -1 ) { out_indexes[out_idx++] = idx; - if (idx > maxval) { + if ( idx > maxval ) { maxval = idx; } } @@ -235,40 +237,45 @@ int find_output_indexes(char *line, struct logparams *lp, struct useropts *bopts * point (everything after the decimal point is ignored). If the time * conversion fails for any reason, then just output the field unmodified. */ -void output_time(const char *field, struct logparams *lp, struct useropts *bopts) { +void output_time(const char* field, struct logparams* lp, struct useropts* bopts) { /* Buffer is declared static in order to reuse the timestamp string */ static char tbuf[MAX_TIMESTAMP_LEN]; - char *tmp; + char* tmp; long tl = strtol(field, &tmp, 10); - if (tl < 0 || tl == LONG_MAX) { + if ( tl < 0 || tl == LONG_MAX ) { fprintf(stderr, "zeek-cut: time value out-of-range: %s\n", field); - } else if (*tmp != '.') { - if (strcmp(field, lp->unsetf)) { + } + else if ( *tmp != '.' ) { + if ( strcmp(field, lp->unsetf) ) { /* field is not a valid value and is not the unset field string */ fprintf(stderr, "zeek-cut: time field is not valid: %s\n", field); } - } else if (tl == lp->prev_ts) { + } + else if ( tl == lp->prev_ts ) { /* timestamp is same as the previous one, so skip the conversion */ fputs(tbuf, stdout); return; - } else { + } + else { time_t tt = tl; struct tm tmval; struct tm* tmptr; tmptr = bopts->timeconv == 1 ? localtime_r(&tt, &tmval) : gmtime_r(&tt, &tmval); - if (tmptr) { - if (strftime(tbuf, sizeof(tbuf), bopts->timefmt, tmptr)) { + if ( tmptr ) { + if ( strftime(tbuf, sizeof(tbuf), bopts->timefmt, tmptr) ) { /* output the formatted timestamp */ fputs(tbuf, stdout); lp->prev_ts = tl; return; - } else { + } + else { fputs("zeek-cut: failed to convert timestamp (try a shorter format string)\n", stderr); } - } else { + } + else { /* the time conversion will fail for large values */ fprintf(stderr, "zeek-cut: time value out-of-range: %s\n", field); } @@ -281,23 +288,23 @@ void output_time(const char *field, struct logparams *lp, struct useropts *bopts /* Output the columns of "line" that the user specified. The value of "hdr" * indicates whether "line" is a header line or not (0=not header, 1=header). */ -void output_indexes(int hdr, char *line, struct logparams *lp, struct useropts *bopts) { +void output_indexes(int hdr, char* line, struct logparams* lp, struct useropts* bopts) { int i; - char *field; - int dotimeconv = 0; /* do a time conversion on this line? (0=no, 1=yes) */ - int dotimetypeconv = 0; /* change time type on this line? (0=no, 1=yes) */ + char* field; + int dotimeconv = 0; /* do a time conversion on this line? (0=no, 1=yes) */ + int dotimetypeconv = 0; /* change time type on this line? (0=no, 1=yes) */ int idxrange = lp->idx_range + hdr; /* header lines have one extra field */ int firstdone = 0; /* If user selected time conversion and this line is not a header line, * then try to do a time conversion. */ - if (bopts->timeconv && !hdr) { + if ( bopts->timeconv && ! hdr ) { dotimeconv = 1; } - for (i = 0; i < idxrange; ++i) { - if ((field = strsep(&line, lp->ifs)) == NULL) { + for ( i = 0; i < idxrange; ++i ) { + if ( (field = strsep(&line, lp->ifs)) == NULL ) { fputs("zeek-cut: skipping log line (not enough fields)\n", stderr); return; } @@ -307,34 +314,35 @@ void output_indexes(int hdr, char *line, struct logparams *lp, struct useropts * /* If user selected time conversion and this line is a "#types" header, * then try to change the "time" type field. */ - if (bopts->timeconv && hdr && !strcmp(lp->tmp_fields[0], "#types")) { + if ( bopts->timeconv && hdr && ! strcmp(lp->tmp_fields[0], "#types") ) { dotimetypeconv = 1; } - if (hdr && bopts->minimalview == 0) { + if ( hdr && bopts->minimalview == 0 ) { /* Output the initial "#" field on the header line */ fputs(lp->tmp_fields[0], stdout); firstdone = 1; } - for (i = 0; i < lp->num_out_indexes; ++i) { + for ( i = 0; i < lp->num_out_indexes; ++i ) { int idxval = lp->out_indexes[i]; - if (firstdone) + if ( firstdone ) fputs(lp->ofs, stdout); - if (idxval != -1) { - if (dotimeconv && lp->time_cols[idxval]) { + if ( idxval != -1 ) { + if ( dotimeconv && lp->time_cols[idxval] ) { /* output time field */ output_time(lp->tmp_fields[idxval], lp, bopts); - } else if (dotimetypeconv && !strcmp("time", lp->tmp_fields[idxval + hdr])) { + } + else if ( dotimetypeconv && ! strcmp("time", lp->tmp_fields[idxval + hdr]) ) { /* change the "time" type field to "string" */ fputs("string", stdout); - } else { + } + else { /* output the field without modification */ fputs(lp->tmp_fields[idxval + hdr], stdout); } - } /* Note: even when idxval == -1, we still need to set "firstdone" so @@ -351,15 +359,15 @@ void output_indexes(int hdr, char *line, struct logparams *lp, struct useropts * */ int zeek_cut(struct useropts bopts) { int ret = 0; - struct logparams lp; /* parameters specific to each log file */ - int headers_seen = 0; /* 0=no header blocks seen, 1=one seen, 2=2+ seen */ - int prev_line_hdr = 0; /* previous line was a header line? 0=no, 1=yes */ + struct logparams lp; /* parameters specific to each log file */ + int headers_seen = 0; /* 0=no header blocks seen, 1=one seen, 2=2+ seen */ + int prev_line_hdr = 0; /* previous line was a header line? 0=no, 1=yes */ int prev_fields_line = 0; /* previous line was #fields line? 0=no, 1=yes */ ssize_t linelen; size_t linesize = 100000; - char *line = (char *) malloc(linesize); + char* line = (char*)malloc(linesize); - if (line == NULL) { + if ( line == NULL ) { fputs("zeek-cut: out of memory\n", stderr); return 1; } @@ -377,24 +385,24 @@ int zeek_cut(struct useropts bopts) { lp.unsetf = strdup("-"); lp.prev_ts = -1; /* initialize with an invalid time value */ - if (lp.unsetf == NULL) { + if ( lp.unsetf == NULL ) { fputs("zeek-cut: out of memory\n", stderr); free(line); return 1; } - while ((linelen = getline(&line, &linesize, stdin)) > 0) { + while ( (linelen = getline(&line, &linesize, stdin)) > 0 ) { /* Remove trailing '\n' */ line[linelen - 1] = '\0'; - if (prev_fields_line && strncmp(line, "#types", 6)) { + if ( prev_fields_line && strncmp(line, "#types", 6) ) { fputs("zeek-cut: bad log header (missing #types line)\n", stderr); ret = 1; break; } /* Check if this line is a header line or not */ - if (line[0] != '#') { + if ( line[0] != '#' ) { prev_line_hdr = 0; output_indexes(0, line, &lp, &bopts); continue; @@ -402,18 +410,18 @@ int zeek_cut(struct useropts bopts) { /* The rest of this loop is for header processing */ - if (!prev_line_hdr) { + if ( ! prev_line_hdr ) { /* Here we are transitioning from non-header to header line */ prev_line_hdr = 1; /* Once we've seen two header blocks, we stop counting them */ - if (headers_seen < 2) { + if ( headers_seen < 2 ) { headers_seen++; } } - if (!strncmp(line, "#separator ", 11)) { + if ( ! strncmp(line, "#separator ", 11) ) { char ifs = parsesep(line + 11); - if (ifs == '\0') { + if ( ifs == '\0' ) { fputs("zeek-cut: bad log header (invalid #separator line)\n", stderr); ret = 1; break; @@ -425,36 +433,40 @@ int zeek_cut(struct useropts bopts) { * use the log file's input field separator. */ lp.ofs[0] = bopts.ofs[0] ? bopts.ofs[0] : lp.ifs[0]; - } else if (!strncmp(line, "#unset_field", 12)) { - if (line[12] && line[13]) { + } + else if ( ! strncmp(line, "#unset_field", 12) ) { + if ( line[12] && line[13] ) { free(lp.unsetf); - if ((lp.unsetf = strdup(line + 13)) == NULL) { + if ( (lp.unsetf = strdup(line + 13)) == NULL ) { fputs("zeek-cut: out of memory\n", stderr); ret = 1; break; } - } else { + } + else { fputs("zeek-cut: bad log header (invalid #unset_field line)\n", stderr); ret = 1; break; } - } else if (!strncmp(line, "#fields", 7)) { + } + else if ( ! strncmp(line, "#fields", 7) ) { prev_fields_line = 1; - if (find_output_indexes(line + 8, &lp, &bopts)) { + if ( find_output_indexes(line + 8, &lp, &bopts) ) { fputs("zeek-cut: out of memory\n", stderr); ret = 1; break; } - } else if (!strncmp(line, "#types", 6)) { - if (!prev_fields_line) { + } + else if ( ! strncmp(line, "#types", 6) ) { + if ( ! prev_fields_line ) { fputs("zeek-cut: bad log header (missing #fields line)\n", stderr); ret = 1; break; } prev_fields_line = 0; - if (bopts.timeconv) { - if (find_timecol(line + 7, &lp)) { + if ( bopts.timeconv ) { + if ( find_timecol(line + 7, &lp) ) { ret = 1; break; } @@ -462,16 +474,16 @@ int zeek_cut(struct useropts bopts) { } /* Decide if we want to output this header */ - if (bopts.showhdr >= headers_seen) { - if (!strncmp(line, "#fields", 7) || (!strncmp(line, "#types", 6) && (bopts.minimalview == 0))) { + if ( bopts.showhdr >= headers_seen ) { + if ( ! strncmp(line, "#fields", 7) || (! strncmp(line, "#types", 6) && (bopts.minimalview == 0)) ) { /* Output a modified "#fields" or "#types" header line */ output_indexes(1, line, &lp, &bopts); - } else if (bopts.minimalview == 0) { + } + else if ( bopts.minimalview == 0 ) { /* Output the header line with no changes */ puts(line); } } - } free(lp.time_cols); @@ -482,13 +494,15 @@ int zeek_cut(struct useropts bopts) { return ret; } -int main(int argc, char *argv[]) { +int main(int argc, char* argv[]) { int c; - char *envtimefmt = getenv("ZEEK_CUT_TIMEFMT"); - if (envtimefmt == NULL) { + char* envtimefmt = getenv("ZEEK_CUT_TIMEFMT"); + if ( envtimefmt == NULL ) { envtimefmt = getenv("BRO_CUT_TIMEFMT"); - if (envtimefmt != NULL) - fprintf(stderr, "zeek-cut warning: using legacy environment variable BRO_CUT_TIMEFMT, set ZEEK_CUT_TIMEFMT instead\n"); + if ( envtimefmt != NULL ) + fprintf( + stderr, + "zeek-cut warning: using legacy environment variable BRO_CUT_TIMEFMT, set ZEEK_CUT_TIMEFMT instead\n"); } struct useropts bopts; @@ -499,13 +513,10 @@ int main(int argc, char *argv[]) { bopts.ofs = ""; bopts.timefmt = envtimefmt ? envtimefmt : "%Y-%m-%dT%H:%M:%S%z"; - static struct option long_opts[] = { - {"help", no_argument, 0, 'h'}, - {0, 0, 0, 0} - }; + static struct option long_opts[] = {{"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; - while ((c = getopt_long(argc, argv, "cCmMnF:duD:U:h", long_opts, NULL)) != -1) { - switch (c) { + while ( (c = getopt_long(argc, argv, "cCmMnF:duD:U:h", long_opts, NULL)) != -1 ) { + switch ( c ) { case 'c': bopts.minimalview = 0; bopts.showhdr = 1; @@ -522,22 +533,16 @@ int main(int argc, char *argv[]) { bopts.minimalview = 1; bopts.showhdr = 2; break; - case 'n': - bopts.negate = 1; - break; + case 'n': bopts.negate = 1; break; case 'F': - if (strlen(optarg) != 1) { + if ( strlen(optarg) != 1 ) { fputs("zeek-cut: field separator must be a single character\n", stderr); exit(1); } bopts.ofs = optarg; break; - case 'd': - bopts.timeconv = 1; - break; - case 'u': - bopts.timeconv = 2; - break; + case 'd': bopts.timeconv = 1; break; + case 'u': bopts.timeconv = 2; break; case 'D': bopts.timeconv = 1; bopts.timefmt = optarg; @@ -546,13 +551,11 @@ int main(int argc, char *argv[]) { bopts.timeconv = 2; bopts.timefmt = optarg; break; - default: - usage(); - break; + default: usage(); break; } } - if (bopts.timeconv && strlen(bopts.timefmt) == 0) { + if ( bopts.timeconv && strlen(bopts.timefmt) == 0 ) { fputs("zeek-cut: time format string cannot be empty\n", stderr); exit(1); }