logtools-0.13d/0000755000175300017530000000000011022146100011552 5ustar rjcrjclogtools-0.13d/clfmerge.cpp0000644000175300017530000002070411022146012014047 0ustar rjcrjc#include #include #include #include #include #include #include #include "logtools.h" #define BUF_SIZE 4096 using namespace std; using namespace __gnu_cxx; struct eqstr { bool operator()(const char *s1, const char *s2) const { return strcmp(s1, s2) == 0; } }; hash_map, eqstr> months; class LogFile { public: LogFile(); ~LogFile(){ if(m_fp) fclose(m_fp); } // open a file, return 0 for success, 1 for minor error (0 length file) // and 2 for serious error (file not found) int open(const char *name, bool domain_mangling); // get the date string of the current item const char *date() const { return m_date; } // get the full data for the current item const char *line() { m_valid = false; return m_line; } // get a line from the file and parse it // return 0 for success and 1 for EOF int getLine(); bool valid() const { return m_valid; } private: bool m_valid; FILE *m_fp; char m_date[17]; char m_lineBuf[BUF_SIZE]; char m_lineBuf2[BUF_SIZE + 7]; char *m_line; bool m_web_first; // store the date in numeric format so that strcmp() can be used to compare // dates. Returns 1 for error and 0 for OK. int setDate(); LogFile(const LogFile&); LogFile & operator=(const LogFile&); }; LogFile::LogFile() : m_valid(false) , m_fp(NULL) { m_line = m_lineBuf; m_lineBuf[0] = '\0'; } // Common log format: // 1.2.3.4 - - [23/Aug/2000:12:00:32 +0200] etc int LogFile::setDate() { unsigned int i; // find '[' or abort if we can't for(i = 0; m_lineBuf[i] != '[' && m_lineBuf[i] != '\0'; i++) { } // if not enough data left for the full date then return if(i + 21 > strlen(m_lineBuf)) return 1; memcpy(m_date, &m_lineBuf[i + 8], 4); char mon[4]; memcpy(mon, &m_lineBuf[i + 4], 3); mon[3] = '\0'; const char *m = months[mon]; if(!m) return 1; strcpy(&m_date[4], m); memcpy(&m_date[6], &m_lineBuf[i + 1], 2); memcpy(&m_date[8], &m_lineBuf[i + 13], 8); m_date[16] = '\0'; if(m_web_first) // make m_lineBuf2 have the data for the mangled line { unsigned int end_webname; // find where the domain name ends for(end_webname = 0; m_lineBuf[end_webname] != ' ' && m_lineBuf[end_webname] != '\0'; end_webname++) { } if(end_webname >= i) return 1; for(i = 0; i < end_webname; i++) m_lineBuf[end_webname] = tolower(m_lineBuf[end_webname]); // there will be more than 40 chars in between unsigned int start_url = end_webname + 40; // search for the start quote character for(; m_lineBuf[start_url] != '\"' && m_lineBuf[start_url] != '\0'; start_url++) { } // search for the space in the web request for(; m_lineBuf[start_url] != ' ' && m_lineBuf[start_url] != '\0'; start_url++) { } if(strlen(&m_lineBuf[start_url]) < 6) return 1; memcpy(m_lineBuf2, &m_lineBuf[end_webname + 1], start_url - end_webname); m_line = &m_lineBuf2[start_url - end_webname]; // m_line points to next char if(strncmp(&m_lineBuf[start_url + 1], "http://", 7)) { strcpy(m_line, "http://"); m_line += 7; memcpy(m_line, m_lineBuf, end_webname); m_line += end_webname; if(m_lineBuf[start_url + 1] != '/') { // if URL doesn't start with a '/' then we add one *m_line = '/'; m_line++; } } strcpy(m_line, &m_lineBuf[start_url + 1]); m_line = m_lineBuf2; } return 0; } int LogFile::open(const char *name, bool domain_mangling) { m_web_first = domain_mangling; m_fp = fopen(name, "r"); if(!m_fp) { fprintf(stderr, "Can't open %s.\n", name); return 2; } if(getLine()) return 1; return 0; } int LogFile::getLine() { while(1) { // if can't get more data then return 1 if(!fgets(m_lineBuf, sizeof(m_lineBuf) - 1, m_fp)) return 1; m_lineBuf[sizeof(m_lineBuf) - 1] = '\0'; m_line = m_lineBuf; strtok(m_line, "\n\r"); // if setDate() returns 1 then we can't parse the line so we keep looping // if setDate() returns 0 then return success! if(!setDate()) { m_valid = true; return 0; } fprintf(stderr, "Skipping bad line: %s\n", m_line); } return 0; // to make compilers happy - will not be reached } typedef LogFile *PLogFile; int item_compare(const void *a, const void *b) { const LogFile * const left = *(LogFile * const *)a; const LogFile * const right = *(LogFile * const *)b; return strcmp(left->date(), right->date()); } struct ltstr { bool operator()(const string s1, const string s2) const { return strcmp(s1.c_str(), s2.c_str()) < 0; } }; void usage(const char *const arg) { fprintf(stderr, "usage: %s [filenames]", arg); fprintf(stderr, "\n" "This program merges web logs in common log format into a single stream\n" "on standard output. It reads from multiple input files and outputs the\n" "data in-order as much as is possible. If there is only a single input\n" "file it will re-order it (with a 1000 line buffer size) to deal with web\n" "servers that output data out of order.\n" "\nVersion: " VERSION "\n"); exit(ERR_PARAM); } int main(int argc, char **argv) { if(argc == 1) return 0; unsigned int map_items = 0; bool set_map_items = false, domain_mangling = false; int int_c; optind = 0; while(-1 != (int_c = getopt(argc, argv, "b:hd")) ) { switch(char(int_c)) { case '?': case ':': case 'h': usage(argv[0]); break; case 'b': set_map_items = true; map_items = atoi(optarg); break; case 'd': domain_mangling = true; break; } } months["Jan"] = "01"; months["Feb"] = "02"; months["Mar"] = "03"; months["Apr"] = "04"; months["May"] = "05"; months["Jun"] = "06"; months["Jul"] = "07"; months["Aug"] = "08"; months["Sep"] = "09"; months["Oct"] = "10"; months["Nov"] = "11"; months["Dec"] = "12"; multimap outputMap; LogFile **items = new PLogFile[argc - optind]; unsigned int item_count = 0; int i; for(i = optind; i < argc; i++) { items[item_count] = new LogFile; int rc = items[item_count]->open(argv[i], domain_mangling); // if rc==2 then file not found, if rc==1 then 0 length file if(rc > 1) return ERR_INPUT; if(rc == 1) delete items[item_count]; else item_count++; } if(!set_map_items) { map_items = item_count * 400; if(map_items < 4000) map_items = 4000; } while(item_count > 1) { qsort(items, item_count, sizeof(LogFile *), item_compare); while(items[0]->valid() && strcmp(items[0]->date(), items[1]->date()) <= 0) { if(map_items > 0) { outputMap.insert(pair(items[0]->date(), items[0]->line())); while(outputMap.size() > map_items) { printf("%s\n", outputMap.begin()->second.c_str()); outputMap.erase(outputMap.begin()); } } else { printf("%s\n", items[0]->line()); } if(items[0]->getLine()) { delete(items[0]); item_count--; items[0] = items[item_count]; break; } } } if(item_count == 1) { if(map_items > 0) { do { outputMap.insert(pair(items[0]->date(), items[0]->line())); } while(!items[0]->getLine() && outputMap.size() < map_items); if(items[0]->valid()) { do { outputMap.insert(pair(items[0]->date(), items[0]->line())); CPCCHAR tmp = outputMap.begin()->second.c_str(); if(printf("%s\n", tmp) != int(strlen(tmp) + 1)) { fprintf(stderr, "Can't write output!\n"); return ERR_OUTPUT; } outputMap.erase(outputMap.begin()); } while(!items[0]->getLine()); } delete items[0]; while(!outputMap.empty()) { CPCCHAR tmp = outputMap.begin()->second.c_str(); if(printf("%s\n", tmp) != int(strlen(tmp) + 1)) { fprintf(stderr, "Can't write output!\n"); return ERR_OUTPUT; } outputMap.erase(outputMap.begin()); } } else { do { CPCCHAR tmp = items[0]->line(); if(printf("%s\n", tmp) != int(strlen(tmp) + 1)) { fprintf(stderr, "Can't write output!\n"); return ERR_OUTPUT; } } while(!items[0]->getLine()); } } delete items; return 0; } logtools-0.13d/Makefile0000644000175300017530000000210407652155404013234 0ustar rjcrjc# Generated automatically from Makefile.in by configure. prefix=/home/rjc/debian/logtools-0.13c/debian/logtools/usr WFLAGS=-Wall -W -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wcast-qual -Woverloaded-virtual -pedantic -ffor-scope CFLAGS=-O2 -g -DNDEBUG ${WFLAGS} CXX=c++ ${CFLAGS} LFLAGS=-lstdc++ INSTALL=/usr/bin/install -c EXES=clfmerge logprn funnel clfsplit clfdomainsplit MAN1=clfmerge.1 logprn.1 funnel.1 clfsplit.1 clfdomainsplit.1 all: $(EXES) %: %.cpp $(CXX) $< -o $@ ${LFLAGS} install-bin: ${EXES} mkdir -p ${prefix}/bin ${INSTALL} -s ${EXES} ${prefix}/bin install: install-bin mkdir -p ${prefix}/share/man/man1 ${prefix}/share/man/man8 ${INSTALL} -m 644 ${MAN1} ${prefix}/share/man/man1 mkdir -p /home/rjc/debian/logtools-0.13c/debian/logtools/etc ${INSTALL} -m 644 clfdomainsplit.cfg /home/rjc/debian/logtools-0.13c/debian/logtools/etc clean: rm -f $(EXES) build-stamp install-stamp rm -rf debian/tmp core debian/*.debhelper rm -f debian/{substvars,files} config.log realclean: clean rm -f configure-stamp config.* Makefile sun/pkginfo logtools.h logtools-0.13d/logtools.h.in0000644000175300017530000000055707275716326014235 0ustar rjcrjc#ifndef LOGTOOLS_H #define LOGTOOLS_H #define VERSION "@version@" typedef const char * PCCHAR; typedef char * PCHAR; typedef PCHAR const CPCHAR; typedef PCCHAR const CPCCHAR; typedef void * PVOID; typedef PVOID const CPVOID; typedef const CPVOID CPCVOID; typedef FILE *PFILE; #define ERR_PARAM 1 #define ERR_INPUT 2 #define ERR_OUTPUT 3 #define ERR_SPEC 4 #endif logtools-0.13d/configure0000755000175300017530000014047207330006161013502 0ustar rjcrjc#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. # Defaults: ac_help= ac_default_prefix=/usr/local # Any additions from configure.in: ac_help="$ac_help --disable-stripping disables stripping of installed binaries" # Initialize some variables set by options. # The variables have the same names as the options, with # dashes changed to underlines. build=NONE cache_file=./config.cache exec_prefix=NONE host=NONE no_create= nonopt=NONE no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= target=NONE verbose= x_includes=NONE x_libraries=NONE bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datadir='${prefix}/share' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' libdir='${exec_prefix}/lib' includedir='${prefix}/include' oldincludedir='/usr/include' infodir='${prefix}/info' mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 ac_prev= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval "$ac_prev=\$ac_option" ac_prev= continue fi case "$ac_option" in -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) ac_optarg= ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case "$ac_option" in -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir="$ac_optarg" ;; -build | --build | --buil | --bui | --bu) ac_prev=build ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build="$ac_optarg" ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file="$ac_optarg" ;; -datadir | --datadir | --datadi | --datad | --data | --dat | --da) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | --da=*) datadir="$ac_optarg" ;; -disable-* | --disable-*) ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` eval "enable_${ac_feature}=no" ;; -enable-* | --enable-*) ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } fi ac_feature=`echo $ac_feature| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "enable_${ac_feature}='$ac_optarg'" ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix="$ac_optarg" ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he) # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat << EOF Usage: configure [options] [host] Options: [defaults in brackets after descriptions] Configuration: --cache-file=FILE cache test results in FILE --help print this message --no-create do not create output files --quiet, --silent do not print \`checking...' messages --version print the version of autoconf that created configure Directory and file names: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [same as prefix] --bindir=DIR user executables in DIR [EPREFIX/bin] --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] --libexecdir=DIR program executables in DIR [EPREFIX/libexec] --datadir=DIR read-only architecture-independent data in DIR [PREFIX/share] --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data in DIR [PREFIX/com] --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] --libdir=DIR object code libraries in DIR [EPREFIX/lib] --includedir=DIR C header files in DIR [PREFIX/include] --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] --infodir=DIR info documentation in DIR [PREFIX/info] --mandir=DIR man documentation in DIR [PREFIX/man] --srcdir=DIR find the sources in DIR [configure dir or ..] --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names EOF cat << EOF Host type: --build=BUILD configure for building on BUILD [BUILD=HOST] --host=HOST configure for HOST [guessed] --target=TARGET configure for TARGET [TARGET=HOST] Features and packages: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR EOF if test -n "$ac_help"; then echo "--enable and --with options recognized:$ac_help" fi exit 0 ;; -host | --host | --hos | --ho) ac_prev=host ;; -host=* | --host=* | --hos=* | --ho=*) host="$ac_optarg" ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir="$ac_optarg" ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir="$ac_optarg" ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir="$ac_optarg" ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir="$ac_optarg" ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst \ | --locals | --local | --loca | --loc | --lo) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) localstatedir="$ac_optarg" ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir="$ac_optarg" ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir="$ac_optarg" ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix="$ac_optarg" ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix="$ac_optarg" ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix="$ac_optarg" ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name="$ac_optarg" ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir="$ac_optarg" ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir="$ac_optarg" ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site="$ac_optarg" ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir="$ac_optarg" ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir="$ac_optarg" ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target="$ac_optarg" ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers) echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` case "$ac_option" in *=*) ;; *) ac_optarg=yes ;; esac eval "with_${ac_package}='$ac_optarg'" ;; -without-* | --without-*) ac_package=`echo $ac_option|sed -e 's/-*without-//'` # Reject names that are not valid shell variable names. if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } fi ac_package=`echo $ac_package| sed 's/-/_/g'` eval "with_${ac_package}=no" ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes="$ac_optarg" ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries="$ac_optarg" ;; -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } ;; *) if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then echo "configure: warning: $ac_option: invalid host type" 1>&2 fi if test "x$nonopt" != xNONE; then { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } fi nonopt="$ac_option" ;; esac done if test -n "$ac_prev"; then { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } fi trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 # File descriptor usage: # 0 standard input # 1 file creation # 2 errors and warnings # 3 some systems may open it to /dev/tty # 4 used on the Kubota Titan # 6 checking for... messages and results # 5 compiler messages saved in config.log if test "$silent" = yes; then exec 6>/dev/null else exec 6>&1 fi exec 5>./config.log echo "\ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. " 1>&5 # Strip out --no-create and --no-recursion so they do not pile up. # Also quote any args containing shell metacharacters. ac_configure_args= for ac_arg do case "$ac_arg" in -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c) ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) ac_configure_args="$ac_configure_args '$ac_arg'" ;; *) ac_configure_args="$ac_configure_args $ac_arg" ;; esac done # NLS nuisances. # Only set these to C if already set. These must not be set unconditionally # because not all systems understand e.g. LANG=C (notably SCO). # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h # AIX cpp loses on an empty file, so make sure it contains at least a newline. echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. ac_unique_file=clfmerge.cpp # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then its parent. ac_prog=$0 ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. srcdir=$ac_confdir if test ! -r $srcdir/$ac_unique_file; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r $srcdir/$ac_unique_file; then if test "$ac_srcdir_defaulted" = yes; then { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } else { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } fi fi srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` # Prefer explicitly selected file to automatically selected ones. if test -z "$CONFIG_SITE"; then if test "x$prefix" != xNONE; then CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" else CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi fi for ac_site_file in $CONFIG_SITE; do if test -r "$ac_site_file"; then echo "loading site script $ac_site_file" . "$ac_site_file" fi done if test -r "$cache_file"; then echo "loading cache $cache_file" . $cache_file else echo "creating cache $cache_file" > $cache_file fi ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross ac_exeext= ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then ac_n= ac_c=' ' ac_t=' ' else ac_n=-n ac_c= ac_t= fi else ac_n= ac_c='\c' ac_t= fi version="0.12a" # Check whether --enable-stripping or --disable-stripping was given. if test "${enable_stripping+set}" = set; then enableval="$enable_stripping" STRIPPING=$strippingval else STRIPPING=no fi if [ ! "$STRIPPING" = "no" ]; then stripping="" else stripping="-s" fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:548: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:578: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" break fi done IFS="$ac_save_ifs" if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# -gt 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift set dummy "$ac_dir/$ac_word" "$@" shift ac_cv_prog_CC="$@" fi fi fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi if test -z "$CC"; then case "`uname -s`" in *win32* | *WIN32*) # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:629: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="cl" break fi done IFS="$ac_save_ifs" fi fi CC="$ac_cv_prog_CC" if test -n "$CC"; then echo "$ac_t""$CC" 1>&6 else echo "$ac_t""no" 1>&6 fi ;; esac fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:661: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF #line 672 "configure" #include "confdefs.h" main(){return(0);} EOF if { (eval echo configure:677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cc_cross=no else ac_cv_prog_cc_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cc_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:703: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 echo "configure:708: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no fi fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes else GCC= fi ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 echo "configure:736: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ac_cv_prog_cc_g=yes else ac_cv_prog_cc_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 if test "$ac_test_CFLAGS" = set; then CFLAGS="$ac_save_CFLAGS" elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 echo "configure:772: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_dummy="$PATH" for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CXX="$ac_prog" break fi done IFS="$ac_save_ifs" fi fi CXX="$ac_cv_prog_CXX" if test -n "$CXX"; then echo "$ac_t""$CXX" 1>&6 else echo "$ac_t""no" 1>&6 fi test -n "$CXX" && break done test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 echo "configure:804: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext << EOF #line 815 "configure" #include "confdefs.h" int main(){return(0);} EOF if { (eval echo configure:820: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cxx_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then ac_cv_prog_cxx_cross=no else ac_cv_prog_cxx_cross=yes fi else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 ac_cv_prog_cxx_works=no fi rm -fr conftest* ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6 if test $ac_cv_prog_cxx_works = no; then { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 echo "configure:846: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 cross_compiling=$ac_cv_prog_cxx_cross echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 echo "configure:851: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.C <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no fi fi echo "$ac_t""$ac_cv_prog_gxx" 1>&6 if test $ac_cv_prog_gxx = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 echo "configure:879: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.cc if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then ac_cv_prog_cxx_g=yes else ac_cv_prog_cxx_g=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6 if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS="$ac_save_CXXFLAGS" elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 echo "configure:911: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else # This must be in double quotes, not single quotes, because CPP may get # substituted into the Makefile and "${CC-cc}" will confuse make. CPP="${CC-cc} -E" # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:932: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:949: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:966: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi rm -f conftest* fi rm -f conftest* fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi CPP="$ac_cv_prog_CPP" else ac_cv_prog_CPP="$CPP" fi echo "$ac_t""$CPP" 1>&6 ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f $ac_dir/install.sh; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break fi done if test -z "$ac_aux_dir"; then { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } fi ac_config_guess=$ac_aux_dir/config.guess ac_config_sub=$ac_aux_dir/config.sub ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 echo "configure:1021: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : else ac_cv_path_install="$ac_dir/$ac_prog -c" break 2 fi fi done ;; esac done IFS="$ac_save_IFS" fi if test "${ac_cv_path_install+set}" = set; then INSTALL="$ac_cv_path_install" else # As a last resort, use the slow shell script. We don't cache a # path for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the path is relative. INSTALL="$ac_install_sh" fi fi echo "$ac_t""$INSTALL" 1>&6 # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' echo $ac_n "checking for working const""... $ac_c" 1>&6 echo "configure:1075: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <j = 5; } { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ const int foo = 10; } ; return 0; } EOF if { (eval echo configure:1129: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_c_const=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_c_const" 1>&6 if test $ac_cv_c_const = no; then cat >> confdefs.h <<\EOF #define const EOF fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 echo "configure:1150: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" { (eval echo configure:1163: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "memchr" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "free" >/dev/null 2>&1; then : else rm -rf conftest* ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF if { (eval echo configure:1230: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 if test $ac_cv_header_stdc = yes; then cat >> confdefs.h <<\EOF #define STDC_HEADERS 1 EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 echo "configure:1254: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else rm -rf conftest* ac_cv_type_size_t=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_type_size_t" 1>&6 if test $ac_cv_type_size_t = no; then cat >> confdefs.h <<\EOF #define size_t unsigned EOF fi echo $ac_n "checking for bind in -lsocket""... $ac_c" 1>&6 echo "configure:1289: checking for bind in -lsocket" >&5 ac_lib_var=`echo socket'_'bind | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi rm -f conftest* LIBS="$ac_save_LIBS" fi if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then echo "$ac_t""yes" 1>&6 extra_ldflags="$extra_ldflags -lsocket -lnsl" else echo "$ac_t""no" 1>&6 fi trap '' 1 2 15 cat > confcache <<\EOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs. It is not useful on other systems. # If it contains results you don't want to keep, you may remove or edit it. # # By default, configure uses ./config.cache as the cache file, # creating it if it does not exist already. You can give configure # the --cache-file=FILE option to use a different cache file; that is # what configure does when it calls configure scripts in # subdirectories, so they share the cache. # Giving --cache-file=/dev/null disables caching, for debugging configure. # config.status only pays attention to the cache file if you give it the # --recheck option to rerun configure. # EOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). sed -n \ -e "s/'/'\\\\''/g" \ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ;; *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ;; esac >> confcache if cmp -s $cache_file confcache; then : else if test -w $cache_file; then echo "updating cache $cache_file" cat confcache > $cache_file else echo "not updating unwritable cache $cache_file" fi fi rm -f confcache trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' # Any assignment to VPATH causes Sun make to only execute # the first set of double-colon rules, so remove it if not needed. # If there is a colon in the path, we need to keep it. if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' fi trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 # Transform confdefs.h into DEFS. # Protect against shell expansion while executing Makefile rules. # Protect against Makefile macro expansion. cat > conftest.defs <<\EOF s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g s%\[%\\&%g s%\]%\\&%g s%\$%$$%g EOF DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` rm -f conftest.defs # Without the "./", some shells look in PATH for config.status. : ${CONFIG_STATUS=./config.status} echo creating $CONFIG_STATUS rm -f $CONFIG_STATUS cat > $CONFIG_STATUS </dev/null | sed 1q`: # # $0 $ac_configure_args # # Compiler output produced by configure, useful for debugging # configure, is in ./config.log if it exists. ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" for ac_option do case "\$ac_option" in -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *) echo "\$ac_cs_usage"; exit 1 ;; esac done ac_given_srcdir=$srcdir ac_given_INSTALL="$INSTALL" trap 'rm -fr `echo "Makefile sun/pkginfo logtools.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 EOF cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF $ac_vpsub $extrasub s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g s%@exec_prefix@%$exec_prefix%g s%@prefix@%$prefix%g s%@program_transform_name@%$program_transform_name%g s%@bindir@%$bindir%g s%@sbindir@%$sbindir%g s%@libexecdir@%$libexecdir%g s%@datadir@%$datadir%g s%@sysconfdir@%$sysconfdir%g s%@sharedstatedir@%$sharedstatedir%g s%@localstatedir@%$localstatedir%g s%@libdir@%$libdir%g s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g s%@version@%$version%g s%@stripping@%$stripping%g s%@CC@%$CC%g s%@CXX@%$CXX%g s%@CPP@%$CPP%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@extra_ldflags@%$extra_ldflags%g CEOF EOF cat >> $CONFIG_STATUS <<\EOF # Split the substitutions into bite-sized pieces for seds with # small command number limits, like on Digital OSF/1 and HP-UX. ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. ac_file=1 # Number of current file. ac_beg=1 # First line for current file. ac_end=$ac_max_sed_cmds # Line after last line for current file. ac_more_lines=: ac_sed_cmds="" while $ac_more_lines; do if test $ac_beg -gt 1; then sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file else sed "${ac_end}q" conftest.subs > conftest.s$ac_file fi if test ! -s conftest.s$ac_file; then ac_more_lines=false rm -f conftest.s$ac_file else if test -z "$ac_sed_cmds"; then ac_sed_cmds="sed -f conftest.s$ac_file" else ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" fi ac_file=`expr $ac_file + 1` ac_beg=$ac_end ac_end=`expr $ac_end + $ac_max_sed_cmds` fi done if test -z "$ac_sed_cmds"; then ac_sed_cmds=cat fi EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then # The file is in a subdirectory. test ! -d "$ac_dir" && mkdir "$ac_dir" ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" # A "../" for each directory in $ac_dir_suffix. ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` else ac_dir_suffix= ac_dots= fi case "$ac_given_srcdir" in .) srcdir=. if test -z "$ac_dots"; then top_srcdir=. else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; *) # Relative path. srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" top_srcdir="$ac_dots$ac_given_srcdir" ;; esac case "$ac_given_INSTALL" in [/$]*) INSTALL="$ac_given_INSTALL" ;; *) INSTALL="$ac_dots$ac_given_INSTALL" ;; esac echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." case "$ac_file" in *Makefile*) ac_comsub="1i\\ # $configure_input" ;; *) ac_comsub= ;; esac ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g s%@INSTALL@%$INSTALL%g " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done rm -f conftest.s* EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF chmod +x $CONFIG_STATUS rm -fr confdefs* $ac_clean_files test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 logtools-0.13d/funnel.10000644000175300017530000000237507352370632013156 0ustar rjcrjc.TH "funnel" "1" "0.06" "Russell Coker " "logtools" .SH "NAME" funnel \- split one pipe stream to one or more files or programs .SH "SYNOPSIS" .B funnel [|] [>[>]file] [|process] .SH "DESCRIPTION" The .B funnel program will read data from standard input and write it to several output streams. .P The .B | symbol means to copy standard input to standard output. .P The .B > symbol means that a file name immediately follows with no separating spaces, the file will be truncated if it exists or created if it doesn't. The .B >> means that the file is to be appended to if it exists. .P A .B | symbol followed immediately by text indicates a command that is to be run by system() and will have all input piped to it. .SH "EXIT STATUS" .B 0 No errors .P .B 1 Error opening input .P Other errors are 100 + number of commands or files that fail .SH "AUTHOR" This program, its manual page, and the Debian package were written by Russell Coker . .SH "FEATURES" Uses .B popen (3) for output so that shell expansion gets performed. If you want such shell expansion then you must ensure that you quote the parameters correctly so that they get expanded by .B popen (3) not the shell that calls .B funnel. .SH "SEE ALSO" .BR popen (3) logtools-0.13d/Makefile.in0000644000175300017530000000160207275716357013656 0ustar rjcrjc prefix=@prefix@ WFLAGS=-Wall -W -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wcast-qual -Woverloaded-virtual -pedantic -ffor-scope CFLAGS=-O2 -g -DNDEBUG ${WFLAGS} CXX=@CXX@ ${CFLAGS} LFLAGS=-lstdc++ @extra_ldflags@ INSTALL=@INSTALL@ EXES=clfmerge logprn funnel clfsplit clfdomainsplit MAN1=clfmerge.1 logprn.1 funnel.1 clfsplit.1 clfdomainsplit.1 all: $(EXES) %: %.cpp $(CXX) $< -o $@ ${LFLAGS} install-bin: ${EXES} mkdir -p ${prefix}/bin @INSTALL_PROGRAM@ @stripping@ ${EXES} ${prefix}/bin install: install-bin mkdir -p @mandir@/man1 @mandir@/man8 @INSTALL_DATA@ ${MAN1} @mandir@/man1 mkdir -p @sysconfdir@ @INSTALL_DATA@ clfdomainsplit.cfg @sysconfdir@ clean: rm -f $(EXES) build-stamp install-stamp rm -rf debian/tmp core debian/*.debhelper rm -f debian/{substvars,files} config.log realclean: clean rm -f configure-stamp config.* Makefile sun/pkginfo logtools.h logtools-0.13d/logprn.10000644000175300017530000000245607352370412013164 0ustar rjcrjc.TH "logprn" "1" "0.06" "Russell Coker " "logtools" .SH "NAME" logprn \- merge Common\-Log Format web logs based on time\-stamps .SH "SYNOPSIS" .B logprn logfile idle\-time[:max\-wait] command .SH "DESCRIPTION" The .B logprn program is designed to print new data that is appended to log files. It will wait until a specified amount of time has elapsed since the last write to the file before printing the data. It will print the data by pipeing it to a specified command. The command will be run by popen(3) so the usual shell commands will operate (whether this is a bug or a feature is a matter of opinion). .SH "OPTIONS" .TP .B logfile specifies a file to read data from. It should be a regular file not a pipe, device, or anything else. .TP .B idle\-time .TP .B max\-wait .TP .B command .SH "EXIT STATUS" .B 0 Never happens, this program will run forever. .P .B 1 Bad command\-line parameters or couldn't stat the log file on startup \- couldn't start the program. .P .B 2 File disappeared or became unreadable at run\-time. .P .B 3 Can't run the specified command. .SH "AUTHOR" This program, its manual page, and the Debian package were written by Russell Coker . .SH "BUGS" Uses .B popen (3) but I consider this a feature not a bug. .SH "SEE ALSO" .BR popen (3) logtools-0.13d/getweblogs0000755000175300017530000000037307273760751013700 0ustar rjcrjc#!/bin/bash # get all logs in sorted order # first parameter is the directory name # second parameter is the flag file name if [ ! -f $1/$2 ]; then touch 1101000072 $1/$2 fi /usr/bin/clfmerge `find $1 -name "access.*" \! -name "*.gz" -newer $1/$2` logtools-0.13d/sample-webalizer.conf0000644000175300017530000003273707323064716015725 0ustar rjcrjc## / Sample Webalizer configuration file / Copyright 1997,1998 by Bradford L. Barrett (brad@mrunix.net) / Edited for Debian by Remco vd Meent (remco@debian.org> / / Distributed under the GNU General Public License. See the / files "Copyright" and "COPYING" provided with the webalizer / distribution for additional information. / / This is a sample configuration file for the Webalizer (ver 1.2x) / Lines starting with pound signs '/' are comment lines and are / ignored. Blank lines are skipped as well. Other lines are considered / as configuration lines, and have the form "ConfigOption Value" where / ConfigOption is a valid configuration keyword, and Value is the value / to assign that configuration option. Invalid keyword/values are / ignored, with appropriate warnings being displayed. There must be / at least one space or tab between the keyword and its value. / / If you want to override the values specified in the configuration / file, specify the '-c filename' option first on the command line. / Additional command line options will override whatever was specified / in the configuration file. You can also use multiple "-c" options / on the command line (why? I don't know, but you can if you really want!). / / As of version 0.98, The Webalizer will look for a 'default' configuration / file named "webalizer.conf" in the current directory, and if not found / there, will look for "/etc/webalizer.conf". If applicable, just copy / the sample configuration to the /etc/ directory, edit to suit and / never have to specify the -c command line option again... / LogFile defines the web server log file to use. If not specified / here or on on the command line, input will default to STDIN. /LogFile /var/log/apache/access.log / OutputDir is where you want to put the output files. This should / should be a full path name, however relative ones might work as well. / If no output directory is specified, the current directory will be used. /OutputDir /var/log/webaliz / HistoryName allows you to specify the name of the history file produced / by the Webalizer. The history file keeps the data for up to 12 months / worth of logs, used for generating the main HTML page (index.html). / The default is a file named "webalizer.hist", stored in the specified / output directory. If you specify just the filename (without a path), / it will be kept in the specified output directory. Otherwise, the path / is relative to the output directory, unless absolute (leading /). /HistoryName webalizer.hist / Incremental processing allows multiple partial log files to be used / instead of one huge one. Useful for large sites that have to rotate / their log files more than once a month. The Webalizer will save its / internal state before exiting, and restore it the next time run, in / order to continue processing where it left off. This mode also causes / The Webalizer to scan for and ignore duplicate records (records already / processed by a previous run). See the README file for additional / information. The value may be 'yes' or 'no', with a default of 'no'. / The file 'webalizer.current' is used to store the current state data, / and is located in the output directory of the program. Incremental yes / IncrementalName allows you to specify the filename for saving the / incremental data in. It is similar to the HistoryName option where the / name is relative to the specified output directory, unless an absolute / filename is specified. The default is a file named "webalizer.current" / kept in the normal output directory. If you don't specify "Incremental" / as 'yes' then this option has no meaning. /IncrementalName webalizer.current / ReportTitle is the text to display as the title. The hostname / (unless blank) is appended to the end of this string (seperated with / a space) to generate the final full title string. / Default is (for english) "Usage Statistics for". /ReportTitle CommandLine / HostName defines the hostname for the report. This is used in / the title, and is prepended to the URL table items. This allows / clicking on URL's in the report to go to the proper location in / the event you are running the report on a 'virtual' web server, / or for a server different than the one the report resides on. / If not specified here, or on the command line, webalizer will / try to get the hostname via a uname system call. If that fails, / it will default to "localhost". /HostName CommandLine / HTMLExtension allows you to specify the filename extension to use / for generated HTML pages. Normally, this defaults to "html", but / can be changed for sites who need it (like for PHP embeded pages). /HTMLExtension html / UseHTTPS should be used if the analysis is being run on a / secure server, and links to urls should use 'https://' instead / of the default 'http://'. If you need this, set it to 'yes'. / Default is 'no'. This only changes the behaviour of the 'Top / URL's' table. /UseHTTPS no / HTMLHead defines HTML code to insert immediately after the / section, before the report title. You can define as many of these / as you want, and they will all be inserted in the order given. / You _MUST_ specify the tag on the first one, do what you / want on the rest (if any). Default is shown below. /HTMLHead / HTMLBody defined the HTML code to be inserted, starting with the / tag. If not specified, the default is shown below. If / used, you MUST include your own tag as the first line. / Maximum line length is 80 char, use multiple lines if needed. /HTMLBody / HTMLPost defines the HTML code to insert immediately before the / first
on the document, which is just after the title and / "summary period"-"Generated on:" lines. If anything, this should / be used to clean up in case an image was inserted with HTMLHead. / As with HTMLHead, you can define as many of these as you want and / they will be inserted in the output stream in order of apperance. /HTMLPost
/ HTMLTail defines the HTML code to insert at the bottom of each / HTML document, usually to include a link back to your home / page or insert a small graphic. It is inserted as a table / data element (ie: your code here ) and is right / alligned with the page. /HTMLTail 100% Micro free! / HTMLEnd defines the HTML code to add at the very end of the / generated files. It defaults to what is shown below. If / used, you MUST specify the and closing tags / as the last lines. Max string length is 80 characters. /HTMLEnd / The Quiet option suppresses output messages... Useful when run / as a cron job to prevent bogus e-mails. Values can be either / "yes" or "no". Default is "no". /Quiet no / ReallyQuiet will supress all messages including errors and / warnings. Values can be 'yes' or 'no' with 'no' being the / default. If 'yes' is used here, it cannot be overriden from / the command line, so use with caution. A value of 'no' has / no effect. /ReallyQuiet no / TimeMe allows you to force the display of timing information / at the end of processing. A value of 'yes' will force the / timing information to be displayed. A value of 'no' has no / effect. /TimeMe no TimeMe yes / GMTTime allows reports to show GMT (UTC) time instead of local / time. Default is to display the time the report was generated / in the timezone of the local machine, such as EDT or PST. This / keyword allows you to have times displayed in UTC instead. /GMTTime no GMTTime yes / Debug prints additional information for error messages. This / will cause webalizer to dump bad records/fields instead of just / telling you it found a bad one. As usual, the value can be / either "yes" or "no". The default is "no". It shouldn't be / needed unless you start getting a lot of Warning or Error / messages and want to see why. (Note: warning and error messages / are printed to stderr, not stdout like normal messages). /Debug no / IgnoreHist shouldn't be used in a config file, but it is here / just because it might be usefull in certain situations. If the / history file is ignored, the main "index.html" file will only / report on the current log files contents. Usefull only when you / want to reproduce the reports from scratch. USE WITH CAUTION! / Valid values are "yes" or "no". Default is "no". /IgnoreHist no / HourlyGraph and HourlyStats allows the hourly statistics graph / and statistics table to be disabled (not displayed). Values / may be "yes" or "no". Default is "yes". HourlyGraph yes HourlyStats yes / The "Top" options below define the number of entries for each table. / Defaults are Sites=30, URL's=30, Referrers=30 and Agents=15, and / Countries=50. Tables may be disabled by using zero (0) for the value. TopSites 30 TopURLs 30 TopKURLs 30 TopReferrers 30 TopAgents 15 TopCountries 500 / The Webalizer normally strips the string 'index.' off the end of / URL's in order to consolidate URL totals. For example, the URL / /somedir/index.html is turned into /somedir/ which is really the / same URL. This option allows you to specify additional strings / to treat in the same way. You don't need to specify 'index.' as / it is always scanned for by The Webalizer, this option is just to / specify _additional_ strings if needed. If you don't need any, / don't specify any as each string will be scanned for in EVERY / log record... A bunch of them will degrade performance. Also, / the string is scanned for anywhere in the URL, so a string of / 'home' would turn the URL /somedir/homepages/brad/home.html into / just /somedir/ which is probably not what was intended. /IndexAlias home.htm /IndexAlias homepage.htm / The Hide*, Group* and Ignore* keywords allow you to change the / way Sites, URL's, Referrers and User Agents are manipulated. The / Ignore* keywords will cause The Webalizer to completely ignore / records as if they didn't exist (and thus not counted in the main / site totals). The Hide* keywords will prevent things from being / displayed in the 'Top' tables, but will still be counted in the / main totals. The Group* keywords allow grouping similar objects / as if they were one. Grouped records are displayed in the 'Top' / tables and can optionally be displayed in BOLD and/or shaded. / Groups cannot be hidden, and are not counted in the main totals. / / The value can have either a leading or trailing '*' wildcard / character. If no wildcard is found, a match can occur anywhere / in the string. Given a string "www.yourmama.com", the values "your", / "*mama.com" and "www.your*" will all match. / Your own site should be hidden /HideSite *host / Your own site gives most referrals /HideReferrer CommandLine/ / This one hides non-referrers ("-" Direct requests) HideReferrer Direct Request / Usually you want to hide these /HideURL *.gif /HideURL *.GIF /HideURL *.jpg /HideURL *.JPG /HideURL *.ra / Hiding agents is kind of futile / HideAgent RealPlayer / Grouping options GroupURL /cgi-bin/* /GroupSite *.aol.com /GroupSite *.compuserve.com /GroupReferrer yahoo.com/ /GroupReferrer excite.com/ /GroupReferrer infoseek.com/ /groupReferrer webcrawler.com/ / The following is a great way to get an overall total / for browsers, and not display all the detail records /GroupAgent MSIE /HideAgent MSIE /GroupAgent Mozilla /HideAgent Mozilla /GroupAgent Lynx* /HideAgent Lynx* / The GroupShading allows grouped rows to be shaded as well. Useful / if your groups intermingle a lot within the table and you want to / diferentate the groups a little more (they are still in bold). / Value can be 'yes' or 'no', with 'yes' being the default. /GroupShading yes / GroupHighlight allows the group record to be displayed in BOLD. / Can be either 'yes' or 'no' with the default 'yes'. /GroupHighlight yes / The Ignore* keywords allow you to completely ignore log records based / on hostname, URL, user agent or referrer. I hessitated in adding these, / since the Webalizer was designed to generate _accurate_ statistics / about a web servers performance. By choosing to ignore records, the / accuracy of reports become skewed, negating why I wrote this program / in the first place. However, due to popular demand, here they are. / Use the same as the Hide*/Group* keywords, where the value can have a / leading or trailing wildcard '*'. /IgnoreSite bad.site.net /IgnoreURL /test* /IgnoreReferrer file:/* /IgnoreAgent RealPlayer / The MangleAgents allows you to specify how much, if any, The Webalizer / should mangle user agent names. This allows several levels of detail / to be produced when reporting user agent statistics. This currently / only works for Netscape and MSIE type browsers. There are six levels / that can be specified, which define different levels of detail / supression. Level 5 shows only the browser name (MSIE or Mozilla) / and the major version number. Level 4 adds the minor version number / (single decimal place). Level 3 displays the minor version to two / decimal places. Level 2 will add any sub-level designation (such / as Mozilla/3.01Gold or MSIE 3.0b). Level 1 will attempt to also add / the system type if it is specified. The default Level 0 displays the / full user agent field without modification and produces the greatest / amount of detail. Browsers other than MSIE and Netscape will always / be left unmodified in the report. MangleAgents 4 / End of configuration file... Have a nice day! /DNSChildren 10 DNSCache /etc/webalizer.dnscache logtools-0.13d/clfsplit.10000644000175300017530000000273307352370402013500 0ustar rjcrjc.TH "clfsplit" "1" "0.06" "Russell Coker " "logtools" .SH "NAME" clfsplit \- split Common\-Log Format web logs based on IP address .SH "SYNOPSIS" .B clfsplit [\-\-help] [\-i input] \-d defaultfile \-f file \-s spec [\-f file \-s spec] .SH "DESCRIPTION" The .B clfsplit will split up large CLF format web logs based on IP address. This is for creating separate log analysis passes for internal and external users of web pages. .SH "OVERVIEW" The .B defaultfile parameter specifies where data goes if it doesn't match any of the IP ranges. This could be /dev/null depending on your aims. .P The .B \-i input parameter gives the file to take input from (default standard input). .P The .B \-f file parameter must be given before the list of IP addresses. .P The .B spec parameter is the IP addresses that go to the file in question. It is of the form .B start[\-end][:start[\-end]] where start and end specify the start and ends of ranges of IPs. Also the .B CIDR notation can be used or a single IP address. If there is a large number of IP ranges then a file name can be given which contains a set of IP ranges, one range per line. .SH "EXIT STATUS" .B 0 No errors .P .B 1 Bad parameters .P .B 2 Can't open input .P .B 3 Can't open/write to output file .P .B 4 Can't open and read from spec file .SH "AUTHOR" This program, its manual page, and the Debian package were written by Russell Coker . .SH "SEE ALSO" .BR clfmerge (1), clfdomainsplit (1) logtools-0.13d/sun/0000755000175300017530000000000007652155404012404 5ustar rjcrjclogtools-0.13d/sun/prototype0000644000175300017530000000056607166360503014401 0ustar rjcrjci pkginfo f none /usr/bin/clfmerge 0755 root root f none /usr/bin/logprn 0755 root root f none /usr/bin/clfsplit 0755 root root f none /usr/bin/funnel 0755 root root f none /usr/share/man/man1/clfmerge.1 0644 root root f none /usr/share/man/man1/logprn.1 0644 root root f none /usr/share/man/man1/clfsplit.1 0644 root root f none /usr/share/man/man1/funnel.1 0644 root root logtools-0.13d/sun/Makefile0000644000175300017530000000055107164572647014057 0ustar rjcrjc all: pkg INSTROOT=`pwd`/tmp PKGNAME=logtools pkg: ( cd .. ; ./configure --prefix=/usr --mandir=`pwd`/sun/tmp/usr/share/man ) make -C .. WFLAGS="-Wall -W -Wshadow -Wpointer-arith -Wwrite-strings" make -C .. prefix=${INSTROOT}/usr install pkgmk -o -r ${INSTROOT} pkgtrans -s spool ${PKGNAME}.pkg ${PKGNAME} echo "/var/spool/pkg/${PKGNAME}.pkg complete!" logtools-0.13d/sun/pkginfo.in0000644000175300017530000000027607213247662014377 0ustar rjcrjcPKG=logtools ARCH=sparc VERSION=@version@ CATEGORY=application NAME=logtools DESC=Utilities for manipulating and managing log files VENDOR=Russell Coker EMAIL=russell@coker.com.au MAXINST=1 logtools-0.13d/sun/pkginfo0000644000175300017530000000027207652155404013765 0ustar rjcrjcPKG=logtools ARCH=sparc VERSION=0.12a CATEGORY=application NAME=logtools DESC=Utilities for manipulating and managing log files VENDOR=Russell Coker EMAIL=russell@coker.com.au MAXINST=1 logtools-0.13d/logtools.h0000644000175300017530000000055307652155404013615 0ustar rjcrjc#ifndef LOGTOOLS_H #define LOGTOOLS_H #define VERSION "0.12a" typedef const char * PCCHAR; typedef char * PCHAR; typedef PCHAR const CPCHAR; typedef PCCHAR const CPCCHAR; typedef void * PVOID; typedef PVOID const CPVOID; typedef const CPVOID CPCVOID; typedef FILE *PFILE; #define ERR_PARAM 1 #define ERR_INPUT 2 #define ERR_OUTPUT 3 #define ERR_SPEC 4 #endif logtools-0.13d/bulk-virtual-webalizer.txt0000644000175300017530000000651407531461436016752 0ustar rjcrjcI have: APACHE_POST_SCRIPT=/usr/local/sbin/runallweblogs Also to have log data from multiple domains in the one log file you need a statement like the following in httpd.conf to save the target domain name at the start of the line: LogFormat "%V %h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" %T" Also you need to load the vhost_alias module: LoadModule vhost_alias_module /usr/lib/apache/1.3/mod_vhost_alias.so You will need to specify which interface to listen on with a Listen directive, and have something similar to the following for re-writing cgi-bin and specifying the virtual document root: RewriteEngine on RewriteRule /cgi-bin/(.*) /cgi-bin/cgiwrap/%{HTTP_HOST}/$1 [PT] VirtualDocumentRoot /home/hosting/%-1/%-2/%-3/%-4+ VirtualScriptAlias /home/hosting/%-1/%-2/%-3/%-4+ UseCanonicalName Off /usr/local/sbin/runallweblogs has the following contents: --- #!/bin/sh /etc/init.d/apache reload ROOTS="/home/chroot/asp /home/chroot/php4" for n in $ROOTS ; do ## First we run the apache logrotate script inside each chroot environment chroot $n /etc/cron.daily/apache ## Then we add its log file to the list. OTH_INPUT="$OTH_INPUT $n/var/log/apache/access.log.1" done export OTH_INPUT /usr/local/sbin/runweblogs --- Edit the /etc/logrotate.d/apache file to run /usr/local/sbin/runallweblogs instead of "/etc/init.d/apache reload". Alternatively if you don't have a chroot environment then you can have logrotate call /usr/local/sbin/runweblogs, in which case you need the apache reload in there. --- The ROOTS variable has the directory names of the chroot environments I use for strange web setups. /usr/local/sbin/runweblogs is separate so that I can easily interrupt things and re-start them manually half way through if necessary, there's nothing preventing you from combining them into one script. /usr/local/sbin/runweblogs has the following contents: --- #!/bin/bash -e INPUT=/var/log/apache/access.log.1 MANGLE=/var/log/apache/mangled.log SPLITDIR=/var/log/apache/split ## clfmerge -d will merge the logs clfmerge -d $INPUT $OTH_INPUT >> $MANGLE ## Run webazolver to do DNS lookups on the log file with ## target domains merged in. webazolver -N30 < $MANGLE & if [ ! -d $SPLITDIR ]; then mkdir $SPLITDIR fi cd $SPLITDIR ## while webazolver is running we split the log file into one file per domain clfdomainsplit -o $SPLITDIR < $MANGLE & ## wait for webazolver to finish (it takes ages) wait if [ ! -d /var/log/apache/webstats/all ]; then mkdir /var/log/apache/webstats/all fi ## Run webalizer on all virtual web servers to give an overview of what the ## entire ISP traffic is. webalizer -o /var/log/apache/webstats/all -t "All ISP customers" < $MANGLE rm $MANGLE ## Now do the per domain processing from a Perl script. /usr/local/sbin/process_logs.pl --- Here's the contents of /usr/local/sbin/process_logs.pl: --- #!/usr/bin/perl use strict; # expects to find CLF logs in the current directory where each log file name # is the name of the domain it belongs to. my @files = `ls -1`; foreach my $file (@files) { chomp $file; my $outputdir = "/var/log/apache/webstats/$file"; mkdir($outputdir, 0775); if(system("webalizer -o $outputdir -t $file -n $file -r $file/ < $file") == 0) { unlink($file) == 1 or printf(STDERR "Can't remove file $file.\n"); } else { printf(STDERR "Error running webalizer!\n"); } } --- logtools-0.13d/logprn.cpp0000644000175300017530000000557407275716551013626 0ustar rjcrjc#include #include #include #include #include #include #include #include #include #include "logtools.h" void usage() { fprintf(stderr, "Usage: logprn logfile idle-time[:max-wait] command\n" "\nVersion: " VERSION "\n"); exit(ERR_PARAM); } int main(int argc, char **argv) { if(argc != 4) usage(); struct stat sBuf; int rc = stat(argv[1], &sBuf); if(rc) { printf("Can't stat \"%s\".\n", argv[1]); return ERR_PARAM; } bool changed = false; time_t mtime = sBuf.st_mtime; ino_t inode = sBuf.st_ino; off_t size = sBuf.st_size; off_t print_size = size; char *pbuf = strdup(argv[2]); strtok(pbuf, ":"); char *maxBuf = strtok(NULL, ":"); time_t delay = atoi(pbuf); time_t maxWait = 0; if(maxBuf) maxWait = atoi(maxBuf); free(pbuf); if(maxWait && maxWait < delay) usage(); if(delay < 1) usage(); time_t last_change = time(NULL); time_t first_unwritten_change = 0; while(1) { sleep(1); rc = stat(argv[1], &sBuf); if(rc) { // if failed then try again 1 second later in case of link changes etc. sleep(1); rc = stat(argv[1], &sBuf); } if(rc) { fprintf(stderr, "File disappeared or became unreadable.\n"); return ERR_INPUT; } if(inode != sBuf.st_ino) { inode = sBuf.st_ino; changed = true; mtime = sBuf.st_mtime; print_size = 0; size = sBuf.st_size; last_change = time(NULL); } else if(mtime != sBuf.st_mtime || size != sBuf.st_size) { if(size > sBuf.st_size) print_size = 0; size = sBuf.st_size; mtime = sBuf.st_mtime; changed = true; last_change = time(NULL); if(first_unwritten_change == 0) first_unwritten_change = last_change; } time_t now = time(NULL); if(changed) { if((now - last_change) > delay || (maxWait && (now - first_unwritten_change ) > maxWait) ) { int fd = open(argv[1], O_RDONLY); if(fd == -1) { fprintf(stderr, "Can't open file \"%s\"\n", argv[1]); return ERR_INPUT; } rc = lseek(fd, print_size, SEEK_SET); if(rc == -1) { fprintf(stderr, "Can't lseek().\n"); } FILE *fp = popen(argv[3], "w"); if(!fp) { fprintf(stderr, "Can't run \"%s\"\n", argv[3]); return ERR_OUTPUT; } char buf[4096]; while( (rc = read(fd, buf, sizeof(buf))) > 0) { if(int(fwrite(buf, 1, rc, fp)) != rc) { fprintf(stderr, "Short write to pipe.\n"); break; } print_size += rc; } pclose(fp); close(fd); changed = false; first_unwritten_change = 0; } } } return 0; // to make gcc happy } logtools-0.13d/debian/0000755000175300017530000000000011022146204013001 5ustar rjcrjclogtools-0.13d/debian/changelog0000644000175300017530000001023211022146204014651 0ustar rjcrjclogtools (0.13d) unstable; urgency=low * Merged changes from NMU and fixed some more GCC 4.3 warnings. -- Russell Coker Fri, 06 Jun 2008 15:34:35 +1000 logtools (0.13c+nmu1) unstable; urgency=medium * Non-maintainer upload. * Fix FTBFS with GCC 4.3 (Closes: #417376). -- Luk Claes Sun, 09 Mar 2008 17:03:20 +0000 logtools (0.13c) unstable; urgency=low * Made it compile with GCC 3.2. -- Russell Coker Fri, 25 Apr 2003 17:09:00 +1000 logtools (0.13b) unstable; urgency=low * Improved documentation that matches how things work in sarge. -- Russell Coker Sun, 1 Sep 2002 15:43:00 +0200 logtools (0.13a) unstable; urgency=LOW * Made clfdomainsplit support URLs with the port number. -- Russell Coker Sun, 2 Dec 2001 23:58:00 +0100 logtools (0.13) unstable; urgency=LOW * Made it work with GCC 3.x. Closes: #121284 -- Russell Coker Mon, 26 Nov 2001 21:46:00 +0100 logtools (0.12b) unstable; urgency=LOW * Fixed some minor documentation bugs, mainly related to funnel. Closes: #112883 -- Russell Coker Thu, 20 Sep 2001 15:40:02 +0200 logtools (0.12a) unstable; urgency=LOW * Fixed header file errors on funnel for hppa. Closes: #104730 -- Russell Coker Sat, 14 Jul 2001 20:04:55 +0200 logtools (0.12) unstable; urgency=LOW * clfmerge -d now converts domain names to lower case. * clfdomainsplit now converts all domain names to lower case internally (for sorting and matching purposes), it still exposes upper-case domains on its output. -- Russell Coker Wed, 11 Jul 2001 17:09:00 +0200 logtools (0.11) unstable; urgency=LOW * Made the "-d" option of clfmerge handle a URL that doesn't contain any '/' characters. -- Russell Coker Tue, 12 Jun 2001 11:58:49 +0200 logtools (0.10) unstable; urgency=MEDIUM * Made clfdomainsplit handle IP addresses and send them to the default file (first code to actually use the default file). * Fixed clfmerge so that the -d option will not mess with a URL that is already fully qualified (checks for "http://" at the start). -- Russell Coker Thu, 7 Jun 2001 23:49:55 +0200 logtools (0.08) unstable; urgency=MEDIUM * Made clfdomainsplit easier to hack (the base code could be used for splitting any text file if 3 small functions are changed). * Make clfdomainsplit use multiple processes to solve file handle limits, this code isn't yet tested... -- Russell Coker Mon, 8 May 2001 13:50:29 +0200 logtools (0.07) unstable; urgency=MEDIUM * Updated the description with more content and fixed some formatting issues. Closes: #78976 * Made it clean the config.cache file (and other config data) before packaging the source. Closes: #96290 * Fixed a bug where clfmerge would output the last line twice if there was only a single log file and buffering was on. * Now "domain name mangling" actually works for clfmerge! * Added new clfdomainsplit program. -- Russell Coker Mon, 7 May 2001 13:52:41 +0200 logtools (0.06) unstable; urgency=low * Add option to change buffer size for clfmerge. * Also added an option for "domain name mangling" to clfmerge. This means that the web logs are expected to have a domain name preceeding the regular CLF format (as suggested in the Apache documentation for mass virtual hosting). See http://www.apache.org/DELETE_ME/vhosts/mass.html . * Fixed a bunch of errors in the man pages. -- Russell Coker Wed, 2 May 2001 18:11:24 +0200 logtools (0.05) unstable; urgency=low * Fixed many trivial bugs. -- Russell Coker Tue, 5 Dec 2000 21:28:54 +0100 logtools (0.04) unstable; urgency=low * Fixed heaps of bugs and ported to Solaris. -- Russell Coker Tue, 14 Nov 2000 21:39:00 +0100 logtools (0.01) unstable; urgency=low * Initial Release. -- Russell Coker Fri, 25 Aug 2000 19:53:08 +0200 logtools-0.13d/debian/control0000644000175300017530000000130307275440566014430 0ustar rjcrjcSource: logtools Section: admin Priority: optional Maintainer: Russell Coker Standards-Version: 3.1.1 Build-Depends: debhelper Package: logtools Architecture: any Depends: ${shlibs:Depends} Description: Russell's misc tools for managing log files. clfmerge - merge common-log-format web logs in order without sorting (good for when you have a gig of logs). . logprn - like "tail -f" but after a specified time period of inactivity will run a program (such as lpr) and pipe the new data to it) . funnel - pipe one stream of data to several files or processes. . clfsplit - split CLF format web logs by client IP address. . clfdomainsplit - split CLF logs by server domain. logtools-0.13d/debian/rules0000755000175300017530000000346207323064736014110 0ustar rjcrjc#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 # This is the debhelper compatability version to use. export DH_COMPAT=2 configure: configure-stamp configure-stamp: dh_testdir # Add here commands to configure the package. ./configure --prefix=`pwd`/debian/logtools/usr --mandir=\$${prefix}/share/man --sysconfdir=`pwd`/debian/logtools/etc touch configure-stamp build: configure-stamp build-stamp build-stamp: dh_testdir # Add here commands to compile the package. $(MAKE) #/usr/bin/docbook-to-man debian/logtools.sgml > logtools.1 touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. -$(MAKE) clean rm -f config.* dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/logtools. $(MAKE) install prefix=`pwd`/debian/logtools/usr # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install # dh_testversion dh_testdir dh_testroot # dh_installdebconf dh_installdocs bulk-virtual-webalizer.txt sample-webalizer.conf # dh_installexamples # dh_installmenu # dh_installemacsen # dh_installpam # dh_installinit # dh_installcron dh_installmanpages # dh_installinfo # dh_undocumented dh_installchangelogs dh_link dh_strip dh_compress dh_fixperms # You may want to make some executables suid here. # dh_suidregister # dh_makeshlibs dh_installdeb # dh_perl dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install logtools-0.13d/debian/docs0000644000175300017530000000000007151531213013650 0ustar rjcrjclogtools-0.13d/debian/copyright0000644000175300017530000000036107151531721014746 0ustar rjcrjcThis package was debianized by Russell Coker on Fri, 25 Aug 2000 19:53:08 +0200. It was downloaded from http://www.coker.com.au/logtools/ Upstream Author(s): Russell Coker Copyright: GPL 2.0 logtools-0.13d/debian/dirs0000644000175300017530000000001007151531742013671 0ustar rjcrjcusr/bin logtools-0.13d/debian/conffiles0000644000175300017530000000003007275505523014707 0ustar rjcrjc/etc/clfdomainsplit.cfg logtools-0.13d/clfmerge.10000644000175300017530000000657407352370260013455 0ustar rjcrjc.TH "clfmerge" "1" "0.06" "Russell Coker " "logtools" .SH "NAME" clfmerge \- merge Common\-Log Format web logs based on time\-stamps .SH "SYNOPSIS" .B clfmerge [\-\-help | \-h] [\-b size] [\-d] [file names] .SH "DESCRIPTION" The .B clfmerge program is designed to avoid using sort to merge multiple web log files. Web logs for big sites consist of multiple files in the >100M size range from a number of machines. For such files it is not practical to use a program such as gnusort to merge the files because the data is not always entirely in order (so the merge option of gnusort doesn't work so well), but it is not in random order (so doing a complete sort would be a waste). Also the date field that is being sorted on is not particularly easy to specify for gnusort (I have seen it done but it was messy). .P This program is designed to simply and quickly sort multiple large log files with no need for temporary storage space or overly large buffers in memory (the memory footprint is generally only a few megs). .SH "OVERVIEW" It will take a number (from 0 to n) of file\-names on the command line, it will open them for reading and read CLF format web log data from them all. Lines which don't appear to be in CLF format (NB they aren't parsed fully, only minimal parsing to determine the date is performed) will be rejected and displayed on standard\-error. .P If zero files are specified then there will be no error, it will just silently output nothing, this is for scripts which use the .B find command to find log files and which can't be counted on to find any log files, it saves doing an extra check in your shell scripts. .P If one file is specified then the data will be read into a 1000 line buffer and it will be removed from the buffer (and displayed on standard output) in date order. This is to handle the case of web servers which date entries on the connection time but write them to the log at completion time and thus generate log files that aren't in order (Netscape web server does this \- I haven't checked what other web servers do). .P If more than one file is specified then a line will be read from each file, the file that had the earliest time stamp will be read from until it returns a time stamp later than one of the other files. Then the file with the earlier time stamp will be read. With multiple files the buffer size is 1000 lines or 100 * the number of files (whichever is larger). When the buffer becomes full the first line will be removed and displayed on standard output. .SH "OPTIONS" .TP .B \-b buffer\-size Specify the buffer\-size to use, if 0 is specified then it means to disable the sliding\-window sorting of the data which improves the speed. .TP .B \-d Set domain\-name mangling to on. This means that if a line starts with .b www.company.com as the name of the site that was requested then that would be removed from the start of the line and the .B "GET /" would be changed to .B "GET http://www.company.com/" which allows programs like Webalizer to produce good graphs for large hosting sites. Also it will make the domain name in lower case. .SH "EXIT STATUS" .B 0 No errors .P .B 1 Bad parameters .P .B 2 Can't open one of the specified files .P .B 3 Can't write to output .SH "AUTHOR" This program, its manual page, and the Debian package were written by Russell Coker . .SH "SEE ALSO" .BR clfsplit (1), clfdomainsplit (1) logtools-0.13d/changes.txt0000777000175300017530000000000011022146317017026 2debian/changelogustar rjcrjclogtools-0.13d/clfsplit.cpp0000644000175300017530000001233011022146100014075 0ustar rjcrjc#include #include #include #include #include #include #include #include #include #include #include "logtools.h" using namespace std; void usage() { fprintf(stderr , "Usage: clfsplit -d defaultfile -f file -s spec [-f file -s spec]\n" "\nSpec is a list of IP ranges or a file containing such a list.\n" "\nVersion: " VERSION "\n"); exit(ERR_PARAM); } class file_wrap { public: file_wrap(FILE *fp, const char *name) : m_fp(fp) , m_name(name) { } void close() { if(m_fp) { fclose(m_fp); m_fp = NULL; } } void write(const char *line) { if(EOF == fputs(line, m_fp)) { fprintf(stderr, "Can't write to output file %s\n", m_name); exit(ERR_OUTPUT); } } private: FILE *m_fp; const char *m_name; file_wrap(const file_wrap&); file_wrap & operator=(const file_wrap&); }; class details; typedef map MAP; const char *inet_itoa(unsigned int ip) { static char buf[30]; sprintf(buf, "%d.%d.%d.%d", ip >> 24, (ip >> 16) % 256, (ip >> 8) % 256, ip % 256); return buf; } class details { public: details(unsigned int begin, unsigned int end, file_wrap *wrap, MAP &m) : m_begin(begin) , m_end(end) , m_wrap(wrap) { m[begin] = this; } ~details() { m_wrap->close(); } bool check_item(unsigned int ip, const char *line) { if(ip >= m_begin && ip <= m_end) { m_wrap->write(line); return true; } return false; } private: unsigned int m_begin, m_end; file_wrap *m_wrap; details(const details&); details & operator=(const details&); }; unsigned int inet_atoi(const char *n) { char tmp[16]; strncpy(tmp, n, sizeof(tmp) - 1); tmp[sizeof(tmp) - 1] = '\0'; for(unsigned int i = 0; i < sizeof(tmp); i++) { if(tmp[i] == ' ') tmp[i] = '\0'; } return ntohl(inet_addr(tmp)); } FILE *open_output_file(const char *file) { if(!file) usage(); const char *mode = "w"; struct stat stat_buf; if(!stat(file, &stat_buf) && S_ISREG(stat_buf.st_mode)) mode = "a"; FILE *output = fopen(file, mode); if(!output) fprintf(stderr, "Can't open file %s\n", file); return output; } void process_spec(MAP &m, const char *file, const char *opt) { FILE *output = open_output_file(file); if(!output) exit(ERR_OUTPUT); file_wrap *wrap = new file_wrap(output, file); FILE *fp = NULL; char buf[4096]; char *ptr = buf; if(opt[0] < '0' || opt[0] > '9') { fp = fopen(opt, "r"); if(!fp) { fprintf(stderr, "Can't open file %s\n", opt); exit(ERR_SPEC); } if(!fgets(buf, sizeof(buf), fp) ) { fprintf(stderr, "Can't read from file %s\n", opt); exit(ERR_SPEC); } } else { ptr = strdup(opt); } do { buf[sizeof(buf) - 1] = '\0'; char *item; item = strtok(ptr, "\r\n:"); do { int i; char *it = strdup(item); for(i = 0; item[i] != '\0' && item[i] != '-' && item[i] != '/'; i++) { } unsigned int first_ip = 0; unsigned int second_ip = 0; switch(item[i]) { case '\0': first_ip = inet_atoi(item); second_ip = first_ip; break; case '-': item[i] = '\0'; first_ip = inet_atoi(item); second_ip = inet_atoi(&item[i + 1]); break; case '/': { item[i] = '\0'; first_ip = inet_atoi(item); unsigned int sub = atoi(&item[i + 1]); second_ip = first_ip + (1 << (32 - sub)) - 1; } break; } new details(first_ip, second_ip, wrap, m); free(it); } while( (item = strtok(NULL, "\r\n:")) ); } while(fp && fgets(buf, sizeof(buf), fp) ); if(fp) fclose(fp); else free(ptr); } int main(int argc, char **argv) { int int_c; const char *defaultfile = NULL; const char *file = NULL; MAP m; FILE *input = stdin; bool new_input = false; optind = 0; while(-1 != (int_c = getopt(argc, argv, "d:i:f:s:")) ) { switch(char(int_c)) { case '?': case ':': usage(); break; case 'd': defaultfile = optarg; break; case 'i': if(new_input) usage(); input = fopen(optarg, "r"); if(!input) { fprintf(stderr, "Can't open file %s\n", optarg); return ERR_INPUT; } new_input = true; break; case 'f': file = optarg; break; case 's': process_spec(m, file, optarg); break; } } new details(0, 0, NULL, m); FILE *def = open_output_file(defaultfile); if(!def) return ERR_OUTPUT; char buf[4096]; while(fgets(buf, sizeof(buf), input)) { buf[sizeof(buf) - 1] = '\0'; unsigned int ip = inet_atoi(buf); if(ip) { MAP::iterator i = m.upper_bound(ip); bool done = false; if(i != m.begin() ) { i--; done = (*i).second->check_item(ip, buf); } if(!done) { if(EOF == fputs(buf, def)) { fprintf(stderr, "Can't write to output file %s\n", defaultfile); return ERR_OUTPUT; } } } } if(new_input) fclose(input); return 0; } logtools-0.13d/clfdomainsplit.cpp0000644000175300017530000002073311022145701015301 0ustar rjcrjc#include #if (__GNUC__ >= 3) #include #else #include #endif #include #include #include #include #include "logtools.h" using namespace std; using namespace __gnu_cxx; // MAX_FDS is the maximum number of files that will be directly written to // by one process #define MAX_FDS 900 // NUM_CHILDREN is the number of child processes that each process may have // Note that each child may also have that many children. The limit is the // size of the process table in your kernel... #define NUM_CHILDREN 100 // Get the "domain" component of the line. Change this if you want to split // on other parts of the name (EG split files on the directory names). Make // sure that the value assigned to dom is a valid file name. // Change this if you want to use this program for splitting files other than // web logs. bool getDomain(string &dom, PCCHAR buf) { if(!(buf = index(buf, '[')) ) return true; if(!(buf = index(buf, ']')) ) return true; if(!(buf = index(buf, '"')) ) return true; if(!(buf = strstr(buf, "http://")) ) return true; buf += 7; PCCHAR end = index(buf, '/'); if(!end) return true; PCCHAR tmp_end = index(buf, ':'); //search for ":80/" at the end and ignore it if(tmp_end && tmp_end < end) end = tmp_end; int len = end - buf; PCHAR tmp = new char[len]; memcpy(tmp, buf, len); for(int i = 0; i < len; i++) tmp[i] = tolower(tmp[i]); dom = string(tmp, int(len)); free(tmp); return false; } // The data structure for configuration. If you change the getDomain() and // canonDom() functions then you'll probably need to change this and the // parseConfig() function. typedef struct { string domain; int significant_parts; } CFG_TYPE; vector config; // Get the canonical name bool canonDom(string &canon, string &dom) { int last = dom.length() - 1; canon = dom; if(canon[last] == '.') { canon.erase(last); last--; // for names that end in '.' } if(isdigit(canon[last])) return true; // canon == dom for numeric ID, and it's not valid for split int significant_parts = 2; unsigned int i; for(i = 0; i < config.size(); i++) { size_t pos = dom.rfind(config[i].domain); if(int(pos) != -1 && (pos + config[i].domain.length()) == dom.length()) { significant_parts = config[i].significant_parts; break; } } for(i = last; i > 0; i--) { if(dom[i] == '.') { significant_parts--; if(!significant_parts) { canon.assign(dom, i + 1, dom.length() - i - 1); break; } } } return false; } void usage(); // This function parses the config file. bool parseConfig(CPCCHAR configFile) { FILE *fp = fopen(configFile, "r"); if(!fp) { fprintf(stderr, "Can't open \"%s\".\n", configFile); usage(); } char buf[1024]; CFG_TYPE cfg; while(fgets(buf, sizeof(buf), fp)) { buf[sizeof(buf) - 1] = '\0'; strtok(buf, "\r\n"); if(strlen(buf) && buf[0] != '#') { cfg.significant_parts = atoi(buf); if(cfg.significant_parts <= 0 || cfg.significant_parts > 10) { fprintf(stderr, "Error in config line \"%s\".\n", buf); return true; } char *ptr = index(buf, ':'); ptr++; if(*ptr == '\0') { fprintf(stderr, "Error in config line \"%s\".\n", buf); return true; } cfg.domain = string(ptr); config.push_back(cfg); } } fclose(fp); return false; } FILE **children[NUM_CHILDREN]; int num_fds = 0; int newTarget = -1; // -1 means handle locally, anything else means the // current child process target FILE *input = stdin; PFILE *defFilePtr; int num_children = 0; struct eqstr { bool operator()(string s1, string s2) const { return s1 == s2; } }; struct hash_string { size_t operator()(const string str) const { return hash()(str.c_str()); } }; typedef hash_map HASH_TYPE; HASH_TYPE fd_map; typedef FILE * PFILE; void usage() { fprintf(stderr, "usage: clfdomainsplit [filenames]\n" "This program splits CLF format web logs into multiple files, one for each\n" "domain in the input.\n" "[-i input] [-d defaultfile] [-c cfg-file] [-o directory]\n" "\nVersion: " VERSION "\n"); exit(ERR_PARAM); } FILE **forkit(string &dom); bool printLine(string &dom, PCCHAR buf); void closeit(); bool newdom(string &dom); FILE **openOutput(string &dom); int main(int argc, char **argv) { for(int i = 0; i < NUM_CHILDREN; i++) { children[i] = NULL; } PCCHAR configFile = "/etc/clfdomainsplit.cfg"; FILE *defFile = stderr; int int_c; optind = 0; while(-1 != (int_c = getopt(argc, argv, "c:d:i:o:")) ) { switch(char(int_c)) { case '?': case ':': usage(); break; case 'c': configFile = optarg; break; case 'd': defFile = fopen(optarg, "a"); if(!defFile) { fprintf(stderr, "Can't open \"%s\".\n", optarg); usage(); } break; case 'i': input = fopen(optarg, "r"); if(!input) { fprintf(stderr, "Can't open \"%s\".\n", optarg); usage(); } break; case 'o': if(chdir(optarg)) { fprintf(stderr, "Can't chdir() to \"%s\".\n", optarg); usage(); } break; } } if(parseConfig(configFile)) return ERR_PARAM; defFilePtr = new PFILE; *defFilePtr = defFile; char buf[4096]; while(fgets(buf, sizeof(buf), input)) { buf[sizeof(buf) - 1] = '\0'; strtok(buf, "\r\n"); string dom; if(getDomain(dom, buf)) { fprintf(stderr, "bad line:%s\n", buf); } else { if(printLine(dom, buf)) { closeit(); return 1; } } } closeit(); return 0; } bool printLine(string &dom, PCCHAR buf) { if(!fd_map[dom]) { if(newdom(dom)) return true; } fprintf(*(fd_map[dom]), "%s\n", buf); return false; } bool newdom(string &dom) { string canon; if(canonDom(canon, dom)) { // send this and anything like it to the default output // beware - a file of totally random junk could run us out of RAM!!! fd_map[canon] = defFilePtr; fd_map[dom] = defFilePtr; return false; } if(fd_map[canon]) { fd_map[dom] = fd_map[canon]; return false; } FILE **fpp = openOutput(canon); if(!fpp) return true; fd_map[dom] = fpp; return false; } FILE **openOutput(string &dom) { if(num_fds > MAX_FDS) { newTarget++; if(newTarget > NUM_CHILDREN) newTarget = 0; } if(newTarget != -1) { if(children[newTarget] == NULL) { return forkit(dom); // NB forkit() can call us } else { fd_map[dom] = children[newTarget]; return children[newTarget]; } } FILE *fp = fopen(dom.c_str(), "a"); if(!fp) { fprintf(stderr, "Can't open/create file \"%s\".\n", dom.c_str()); return NULL; } num_fds++; FILE **val = new PFILE; *val = fp; fd_map[dom] = val; return val; } FILE **forkit(string &dom) { int filedes[2], childFiledes[2]; if(pipe(filedes) || pipe(childFiledes)) { fprintf(stderr, "Can't create pipe!\n"); return NULL; } fflush(NULL); int rc = fork(); if(rc == -1) { fprintf(stderr, "Can't fork!\n"); return NULL; } char c; if(rc == 0) { // child closeit(); num_fds = 0; newTarget = -1; num_children = 0; for(int i = 0; i < NUM_CHILDREN; i++) { children[i] = NULL; } close(childFiledes[0]); write(childFiledes[1], &c, 1); close(childFiledes[1]); close(filedes[1]); input = fdopen(filedes[0], "r"); if(!input) { fprintf(stderr, "Can't fdopen!\n"); close(filedes[0]); exit(1); } return openOutput(dom); } else { // parent num_children++; close(filedes[0]); close(childFiledes[1]); read(childFiledes[0], &c, 1); close(childFiledes[0]); FILE *fp = fdopen(filedes[1], "w"); if(!fp) { fprintf(stderr, "Can't fdopen!\n"); return NULL; } FILE **fpp = new PFILE; *fpp = fp; children[newTarget] = fpp; fd_map[dom] = children[newTarget]; return children[newTarget]; } return NULL; // should never reach here } void closeit() { while(!fd_map.empty()) { HASH_TYPE::iterator st = fd_map.begin(); FILE **fpp = (*st).second; if(fpp) { if(*fpp) { fclose(*fpp); } *fpp = NULL; } fd_map.erase(st); } } logtools-0.13d/configure.in0000644000175300017530000000131007324104554014077 0ustar rjcrjcdnl Process this file with autoconf to produce a configure script. AC_INIT(clfmerge.cpp) AC_SUBST(version) version="0.12a" AC_ARG_ENABLE(stripping, [ --disable-stripping disables stripping of installed binaries], STRIPPING=$strippingval, STRIPPING=no) AC_SUBST(stripping) if [[ ! "$STRIPPING" = "no" ]]; then stripping="" else stripping="-s" fi dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_CPP AC_PROG_INSTALL dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T dnl Checks for library -l socket. AC_SUBST(extra_ldflags) AC_CHECK_LIB(socket, bind, extra_ldflags="$extra_ldflags -lsocket -lnsl") AC_OUTPUT(Makefile sun/pkginfo logtools.h) logtools-0.13d/sh.common0000644000175300017530000001067307166360616013435 0ustar rjcrjc## ## This file is part of shtool and free software; you can redistribute ## it and/or modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either version ## 2 of the License, or (at your option) any later version. ## ## This file is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA, or contact Ralf S. Engelschall . ## ## ## COMMON UTILITY CODE ## # determine name of tool if [ ".$tool" != . ]; then # used inside shtool script toolcmd="$0 $tool" toolcmdhelp="shtool $tool" msgprefix="shtool:$tool" else # used as standalone script toolcmd="$0" toolcmdhelp="sh $0" msgprefix="$str_tool" fi # parse argument specification string eval `echo $arg_spec |\ sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` # parse option specification string eval `echo h.$opt_spec |\ sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` # interate over argument line opt_PREV='' while [ $# -gt 0 ]; do # special option stops processing if [ ".$1" = ".--" ]; then shift break fi # determine option and argument opt_ARG_OK=no if [ ".$opt_PREV" != . ]; then # merge previous seen option with argument opt_OPT="$opt_PREV" opt_ARG="$1" opt_ARG_OK=yes opt_PREV='' else # split argument into option and argument case "$1" in -[a-zA-Z0-9]*) eval `echo "x$1" |\ sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ -e 's/";\(.*\)$/"; opt_ARG="\1"/'` ;; -[a-zA-Z0-9]) opt_OPT=`echo "x$1" | cut -c3-` opt_ARG='' ;; *) break ;; esac fi # eat up option shift # determine whether option needs an argument eval "opt_MODE=\$opt_MODE_${opt_OPT}" if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then opt_PREV="$opt_OPT" continue fi fi # process option case $opt_MODE in '.' ) # boolean option eval "opt_${opt_OPT}=yes" ;; ':' ) # option with argument (multiple occurances override) eval "opt_${opt_OPT}=\"\$opt_ARG\"" ;; '+' ) # option with argument (multiple occurances append) eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" ;; * ) echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 exit 1 ;; esac done if [ ".$opt_PREV" != . ]; then echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 exit 1 fi # process help option if [ ".$opt_h" = .yes ]; then echo "Usage: $toolcmdhelp $str_usage" exit 0 fi # complain about incorrect number of arguments case $arg_MODE in '=' ) if [ $# -ne $arg_NUMS ]; then echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 exit 1 fi ;; '+' ) if [ $# -lt $arg_NUMS ]; then echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 exit 1 fi ;; esac # establish a temporary file on request if [ ".$gen_tmpfile" = .yes ]; then if [ ".$TMPDIR" != . ]; then tmpdir="$TMPDIR" elif [ ".$TEMPDIR" != . ]; then tmpdir="$TEMPDIR" else tmpdir="/tmp" fi tmpfile="$tmpdir/.shtool.$$" rm -f $tmpfile >/dev/null 2>&1 touch $tmpfile fi logtools-0.13d/clfdomainsplit.cfg0000644000175300017530000000004107307772450015266 0ustar rjcrjc2:com 2:net 2:org 2:nl 3:au 3:uk logtools-0.13d/clfdomainsplit.10000644000175300017530000000430207352370362014667 0ustar rjcrjc.TH "clfdomainsplit" "1" "0.06" "russell@coker.com.au" "1" .SH "NAME" clfdomainsplit \- split Common\-Log Format web logs based on domain name .SH "SYNOPSIS" .B clfdomainsplit [\-\-help] [\-i input] [\-d defaultfile] [\-c cfg\-file] [\-o directory] .SH "DESCRIPTION" The .B clfdomainsplit program will split up large CLF format web logs based on domain name. This is for creating separate log analysis passes for each domain hosted on your server. .SH "OVERVIEW" The .BR input parameter specifies the file to read (default is standard input). .P The .BR defaultfile parameter specifies where data goes if it doesn't have a domain (either it has an IP address for the server or it doesn't have the server\-name \- the URL is relative to the root of the web server only). The default will be to print them on standard error. .P The .BR cfg\-file parameter is for specifying the rules for determining what is a different domain name. For example www.coker.com.au belongs in the same file as coker.com.au and abc.coker.com.au because domain names ending in .au have three major components. The domain names www.workbenelux.nl and workbenelux.nl belong in the same file because domain names ending in .nl have two major components (as do .com, and .gov), wheras anything ending in .va belongs to the same organization. The rules are of the form .BR number:pattern which lists the number of domain parts which are significant (2 for .com and .nl domains, 3 for .au and .uk domains, and 1 for .va. The pattern is used for a simple string comparison, the default will be: .TP 2:com .TP 2:nl .TP 3:au .TP 3:uk .P If no config file is specified then it will look for .BR /etc/clfdomainsplit.cfg . Of course comments start with #. Also note that the first match will be used! .P The .BR directory parameter is to specify the location for the files to be created (default is the current directory). I recommend that you use a directory for this and nothing else as you never know how many files may be created! .SH "EXIT STATUS" .B 0 No errors .P .B 1 Bad parameters .SH "AUTHOR" This program, its manual page, and the Debian package were written by Russell Coker . .SH "SEE ALSO" .BR clfsplit (1), clfmerge (1) logtools-0.13d/funnel.cpp0000644000175300017530000000322707324104573013573 0ustar rjcrjc#include #include #include #include #include #include "logtools.h" void usage() { fprintf(stderr, "Usage: funnel [|] [>[>]file] [|program]\n" "\nVersion: " VERSION "\n"); exit(ERR_PARAM); } PFILE openit(const char *arg) { const char *ptr = arg; PFILE ret = NULL; if(!strcmp(arg, "|")) return stdout; if(ptr[0] == '>') { const char *mode = "w"; ptr++; if(ptr[0] == '>') { ptr++; mode = "a"; } ret = fopen(ptr, mode); } else if(ptr[0] == '|') { ptr++; ret = popen(ptr, "w"); } else { fprintf(stderr, "Bad command \"%s\".\n", arg); return NULL; } return ret; } int main(int argc, char **argv) { if(argc < 2) usage(); PFILE *out = new PFILE[argc]; int i; for(i = 1; i < argc; i++) { out[i] = openit(argv[i]); } char buf[8192]; size_t rc; int count = argc - 1; int errors = 0; int f = fcntl(0, F_GETFL); if(f == -1 || -1 == fcntl(0, F_SETFL, f & (!O_NONBLOCK)) ) { fprintf(stderr, "Can't fcntl\n"); return ERR_INPUT; } while( int(rc = read(0, buf, sizeof(buf)) ) > 0 && count > 0) { if(rc) { for(i = 1; i < argc; i++) { if(out[i]) { size_t wrote = fwrite(buf, rc, 1, out[i]); if(wrote != 1) { fclose(out[i]); out[i] = NULL; fprintf(stderr, "Output \"%s\" aborted.\n", argv[i]); count--; errors++; } } } fflush(NULL); } } close(0); for(i = 1; i < argc; i++) { if(out[i]) fclose(out[i]); } return 100 + errors; } logtools-0.13d/install.sh0000755000175300017530000001067507166360616013620 0ustar rjcrjc## ## install -- Install a program, script or datafile ## Copyright (c) 1997-2000 Ralf S. Engelschall ## Originally written for shtool ## ## This file is part of shtool and free software; you can redistribute ## it and/or modify it under the terms of the GNU General Public ## License as published by the Free Software Foundation; either version ## 2 of the License, or (at your option) any later version. ## ## This file is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ## USA, or contact Ralf S. Engelschall . ## str_tool="install" str_usage="[-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g] [-e] [ ...] " arg_spec="2+" opt_spec="v.t.c.C.s.m:o:g:e:" opt_v=no opt_t=no opt_c=no opt_C=no opt_s=no opt_m="" opt_o="" opt_g="" opt_e="" . ./sh.common # determine source(s) and destination argc=$# srcs="" while [ $# -gt 1 ]; do srcs="$srcs $1" shift done dstpath="$1" # type check for destination dstisdir=0 if [ -d $dstpath ]; then dstpath=`echo "$dstpath" | sed -e 's:/$::'` dstisdir=1 fi # consistency check for destination if [ $argc -gt 2 -a $dstisdir = 0 ]; then echo "$msgprefix:Error: multiple sources require destination to be directory" 1>&2 exit 1 fi # iterate over all source(s) for src in $srcs; do dst=$dstpath # If destination is a directory, append the input filename if [ $dstisdir = 1 ]; then dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` dst="$dst/$dstfile" fi # Add a possible extension to src and dst if [ ".$opt_e" != . ]; then src="$src$opt_e" dst="$dst$opt_e" fi # Check for correct arguments if [ ".$src" = ".$dst" ]; then echo "$msgprefix:Warning: source and destination are the same - skipped" 1>&2 continue fi if [ -d "$src" ]; then echo "$msgprefix:Warning: source \`$src' is a directory - skipped" 1>&2 continue fi # Make a temp file name in the destination directory dsttmp=`echo $dst |\ sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;' \ -e "s;\$;/#INST@$$#;"` # Verbosity if [ ".$opt_v" = .yes ]; then echo "$src -> $dst" 1>&2 fi # Copy or move the file name to the temp name # (because we might be not allowed to change the source) if [ ".$opt_C" = .yes ]; then opt_c=yes fi if [ ".$opt_c" = .yes ]; then if [ ".$opt_t" = .yes ]; then echo "cp $src $dsttmp" 1>&2 fi cp $src $dsttmp || exit $? else if [ ".$opt_t" = .yes ]; then echo "mv $src $dsttmp" 1>&2 fi mv $src $dsttmp || exit $? fi # Adjust the target file # (we do chmod last to preserve setuid bits) if [ ".$opt_s" = .yes ]; then if [ ".$opt_t" = .yes ]; then echo "strip $dsttmp" 1>&2 fi strip $dsttmp || exit $? fi if [ ".$opt_o" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chown $opt_o $dsttmp" 1>&2 fi chown $opt_o $dsttmp || exit $? fi if [ ".$opt_g" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chgrp $opt_g $dsttmp" 1>&2 fi chgrp $opt_g $dsttmp || exit $? fi if [ ".$opt_m" != . ]; then if [ ".$opt_t" = .yes ]; then echo "chmod $opt_m $dsttmp" 1>&2 fi chmod $opt_m $dsttmp || exit $? fi # Determine whether to do a quick install # (has to be done _after_ the strip was already done) quick=no if [ ".$opt_C" = .yes ]; then if [ -r $dst ]; then if cmp -s $src $dst; then quick=yes fi fi fi # Finally install the file to the real destination if [ $quick = yes ]; then if [ ".$opt_t" = .yes ]; then echo "rm -f $dsttmp" 1>&2 fi rm -f $dsttmp else if [ ".$opt_t" = .yes ]; then echo "rm -f $dst && mv $dsttmp $dst" 1>&2 fi rm -f $dst && mv $dsttmp $dst fi done