/* ---------------------------------------------------------------------- (C) Copyright Marxmeier Software AG 2006,2007,2008 Project: Eloquence database File: fwmemo.c Function: fw log test with memo api Edit History: 24.05.2006, rhg - creation 29.03.2007, rhg - integrate session info api 13.03.2008, rhg - integrate memo api ---------------------------------------------------------------------- */ static const char RcsId[] = "$Id: fwmemo.c,v 25.1 2008/04/23 13:41:32 mike Exp $"; #if defined(_WIN32) #include #endif #include #include #include #include #if defined(_WIN32) #include "getopt.h" #endif #include "fwutil.h" /*------------------------------------------------------------------------ module definitions ------------------------------------------------------------------------*/ #define DEFAULT_STATUS_FILE "fwmemo.stat" /*------------------------------------------------------------------------ forward references ------------------------------------------------------------------------*/ static char *argv0; static int verbose; static void usage(void); static int test_cb(int db_node_id, const char *db_name, const char *set_name, time_t timestamp, enum Fwu_OP op, unsigned int recno, int recsz, const void *bi_rec, const void *ai_rec); static int memo_cb(time_t timestamp, int mode, const void *data, int data_sz); /*------------------------------------------------------------------------ main ------------------------------------------------------------------------*/ #if defined(_WIN32) HINSTANCE hInst; #endif int main(int argc, char *argv[]) { extern char *optarg; extern int optind, /* opterr, */ optopt; int c; int errflg; char *cfg_file; char *status_file; char *fwlog_generation; int print_status; #if defined(_WIN32) hInst = (HINSTANCE)GetModuleHandle(NULL); #endif /* ---------------------------------------- welcome ---------------------------------------- */ argv0 = argv[0]; if(argc == 2 && !strcmp(argv[1], "-help")) usage(); /* ---------------------------------------- handle commandline args ---------------------------------------- */ cfg_file = NULL; status_file = DEFAULT_STATUS_FILE; fwlog_generation = NULL; print_status = 0; errflg = 0; while( (c = getopt(argc,argv, "c:vSf:n:I")) != EOF ) { switch(c) { case 'c': cfg_file = optarg; break; case 'v': verbose++; Fwu_verbose(1); break; case 'S': Fwu_synconly(1); break; case 'f': status_file = optarg; break; case 'n': fwlog_generation = optarg; break; case 'I': print_status = 1; break; case ':': fprintf(stderr, "Option -%c requires an argument\n", optopt); errflg++; break; case '?': fprintf(stderr, "Unrecognized option: - %c\n", optopt); errflg++; break; default: errflg++; break; } } if( optind != argc ) { fprintf(stderr, "%s: Unexpected arguments\n", argv[0]); errflg++; } if( errflg ) usage(); if(print_status) { if(verbose) printf("%s:\n", status_file); Fwu_status(status_file, verbose); return 0; } /* ---------------------------------------- process fwlog ---------------------------------------- */ Fwu_set_memo_callback(memo_cb); return Fwu_process(test_cb, cfg_file, status_file, fwlog_generation); } /*------------------------------------------------------------------------ usage ------------------------------------------------------------------------*/ static void usage() { fprintf(stderr, "usage: %s [options]\n", argv0); fprintf(stderr, "options:\n"); fprintf(stderr, " -help - show usage (this list)\n"); fprintf(stderr, " -c cfg - server configuration file\n"); fprintf(stderr, " -v - verbose, display progress\n"); fprintf(stderr, " -S - synchronize on existing log, then exit\n"); fprintf(stderr, " -f statfile - status file (default: %s)\n", DEFAULT_STATUS_FILE); fprintf(stderr, " -n generation - initialize from forward-log generation\n"); fprintf(stderr, " -I - print status file (-v to output details)\n"); fprintf(stderr, "\n"); exit(2); } /*------------------------------------------------------------------------ callback ------------------------------------------------------------------------*/ static int test_cb(int db_node_id, const char *db_name, const char *set_name, time_t timestamp, enum Fwu_OP op, unsigned int recno, int recsz, const void *bi_rec, const void *ai_rec) { const char *op_str; struct tm *tm; char tmp[32]; int memo_pass; switch (op) { case Fwu_OP_PUT: assert(bi_rec == NULL); assert(ai_rec != NULL); op_str = "DBPUT"; break; case Fwu_OP_UPDATE: assert(bi_rec != NULL); assert(ai_rec != NULL); op_str = "DBUPDATE"; break; case Fwu_OP_DELETE: assert(bi_rec != NULL); assert(ai_rec == NULL); op_str = "DBDELETE"; break; default: assert(!"unexpected image op"); } printf("%s %s.%s recno=%u\n", op_str, db_name, set_name, recno); if( verbose > 1 ) { const char *login = Fwu_get_session_entry("login"); const char *pname = Fwu_get_session_entry("pname"); printf(" session=%d login=%s pname=%s\n", Fwu_get_session_id(), login ? login : "", pname ? pname : ""); } if( verbose > 2 ) { int i, cnt = Fwu_get_session_elements(); for (i = 0; i < cnt; i++) printf(" session_data[%d]=%s\n", i, Fwu_get_session_data(i)); } tm = localtime(×tamp); strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", tm); printf(" action=%u-%u.%u %s\n", Fwu_CurrentLogGeneration(), Fwu_CurrentLogSequence(), Fwu_CurrentTagSequence(), tmp); for( memo_pass = 0; memo_pass < 3; memo_pass++ ) { char *memo_mode_s; const void *memo_data; int memo_data_sz; time_t memo_timestamp; switch( memo_pass ) { case 0: memo_mode_s = "DBBEGIN"; memo_data = Fwu_get_memo(Fwu_MEMO_DBBEGIN, &memo_timestamp, &memo_data_sz); break; case 1: memo_mode_s = "DBEND"; memo_data = Fwu_get_memo(Fwu_MEMO_DBEND, &memo_timestamp, &memo_data_sz); break; case 2: memo_mode_s = "DBMEMO"; memo_data = Fwu_get_memo(Fwu_MEMO_DBMEMO, &memo_timestamp, &memo_data_sz); } if( memo_data == NULL ) continue; tm = localtime(&memo_timestamp); strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", tm); printf(" context:%s size:%d timestamp: %s\n", memo_mode_s, memo_data_sz, tmp); if( memo_data_sz ) { const char *p = memo_data; putchar(' '); putchar(' '); while( memo_data_sz-- > 0 ) { unsigned char ch = *p++; if( ch < 0x20 || (ch >= 0x80 && ch < 0xa0) ) printf("\\%03o", ch); else { if( ch == '\\' ) putchar('\\'); putchar(ch); } } putchar('\n'); } } fflush(stdout); return 0; } static int memo_cb(time_t timestamp, int mode, const void *data, int data_sz) { struct tm *tm; char tmp[32]; printf("MEMO session:%d mode:", Fwu_get_session_id()); switch( mode ) { case Fwu_MEMO_DBBEGIN: fputs("DBBEGIN", stdout); break; case Fwu_MEMO_DBEND: fputs("DBEND", stdout); break; case Fwu_MEMO_DBMEMO: fputs("DBMEMO", stdout); break; default: printf("%d", mode); } tm = localtime(×tamp); strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", tm); printf(" size:%d timestamp: %s\n", data_sz, tmp); if( data_sz ) { const char *p = data; putchar(' '); while( data_sz-- > 0 ) { unsigned char ch = *p++; if( ch < 0x20 || (ch >= 0x80 && ch < 0xa0) ) printf("\\%03o", ch); else { if( ch == '\\' ) putchar('\\'); putchar(ch); } } putchar('\n'); } fflush(stdout); return 0; }