/*** DTB_USER_CODE_START vvv Add file header below vvv ***/ /* $TOG: ttsnoop.C.src /main/8 1999/09/20 16:07:27 mgreess $ */ /*** DTB_USER_CODE_END ^^^ Add file header above ^^^ ***/ /* * File: ttsnoop.c * Contains: main() and cross-module connections * * This file was generated by dtcodegen, from project ttsnoop * * Any text may be added between the DTB_USER_CODE_START and * DTB_USER_CODE_END comments (even non-C code). Descriptive comments * are provided only as an aid. * * ** EDIT ONLY WITHIN SECTIONS MARKED WITH DTB_USER_CODE COMMENTS. ** * ** ALL OTHER MODIFICATIONS WILL BE OVERWRITTEN. DO NOT MODIFY OR ** * ** DELETE THE GENERATED COMMENTS! ** */ #include #include #include #include #include #include #include #include #include #include #include #include
#include
#include
#include #include
#include
#include "ttsnoop_ui.h" #include "apiTracer_ui.h" #include "ttChooser_ui.h" #include "patternProps_ui.h" #include "stringChooser_ui.h" #include "messageProps_ui.h" #include "sessionChooser_ui.h" #include "fileChooser_ui.h" #include "argChooser_ui.h" #include "callbackChooser_ui.h" #include "ttsnoop.h" #include "dtb_utils.h" /************************************************************************** *** DTB_USER_CODE_START *** *** All necessary header files have been included. *** *** Add include files, types, macros, externs, and user functions here. ***/ #include #include #include #include #include #include #include #include #include #include
#include #include #include "tt_c++.h" #include "DtTt.h" //#include //#include //extern "C" { Pixmap XmeGetMask( Screen *, const char * ); } Boolean optImmediateTracing = False; Boolean optMapOnOutput = False; Boolean optImmediateSnooping = True; Boolean optImmediateTtOpen = True; Boolean optImmediateXSession = False; char * optImmediateSession = 0; Tt_pattern snoopPat = 0; Boolean snoopPatIsRegistered = False; char * snoopFile = 0; Boolean unlinkSnoopFile = True; char * traceFile = 0; Boolean unlinkTraceFile = True; std::string traceScript; int globalTimeout = 20000; unsigned int globalSaveLines = 5000; const char * globalVersionString = "1.0"; char ** scopeFiles = 0; unsigned int scopeFilesCount = 0; char ** ops = 0; unsigned int opsCount = 0; char ** senders = 0; unsigned int sendersCount = 0; char * vtype = 0; pid_t snoopedPid = -1; char ** snoopedArgs = 0; unsigned int snoopedArgsCount = 0; char * optTraceScript = 0; String apiTracerArgv[ 10 ]; String snooperArgv[ 10 ]; std::ostringstream tttraceCmd; std::ofstream snoopStream; // Xt squats on -tf ?! XXX const char Usage[] = "ttsnoop - ToolTalk graphical user interface\n" "Usage: ttsnoop [options] [-F scopefile] [-< procid] [-v media] [-m op]\n" " ttsnoop [options] -n|-N\n" " ttsnoop [options] [-e script] command [args]\n" "\n" "-F scopefile scope initial pattern also to scopefile\n" "-\\< \"procid\" limit initial pattern to messages from procid\n" "-v mediaType limit initial pattern to messages for mediaType\n" "-m op limit initial pattern to given op\n" "\n" "-n skip initial pattern\n" "-N skip initial ttdt_open(), also\n" "\n" "command [args] invoke command [with args] and snoop its TT API calls\n" "-e script Take script as a tttrace setting. See tttracefile(4).\n" "\n" "options ::= [-Tu] [-S sessid] [-w n] [-l n] [-o snoopfile] [-O tracefile]\n" "-T trace (even initial) TT API calls made by ttsnoop\n" "-u map (de-iconify) on snoop output\n" "-S sessid set default session to sessid\n" "-X set default session to tt_X_session of $DISPLAY\n" "-w n set global timeout to n seconds [default: 20]\n" "-l n set tttrace dtterm saveLines to n lines [default: 5000]\n" "-o snoopfile log snoop output to snoopfile\n" "-O tracefile log api tracing to tracefile\n" "\n" "-xrm \"*DtTerm.saveLines: n\"\n" "-xrm \"*DtTerm.rows: n\"\n" "-xrm \"*DtTerm.columns: n\"\n" "-xrm \"*DtTerm.mapOnOutput: true\"\n"; static void cleanUp() { if (unlinkSnoopFile) { if (unlink( snoopFile ) == -1) { clog << "ttsnoop: unlink( \"" << snoopFile; clog << "\"): " << strerror( errno ) << endl; } else { unlinkSnoopFile = False; } } if (unlinkTraceFile) { if (unlink( traceFile ) == -1) { clog << "ttsnoop: unlink( \"" << traceFile; clog << "\"): " << strerror( errno ) << endl; } else { unlinkTraceFile = False; } } } static void signalHandler( int sig ) { pid_t child; int status; switch (sig) { case SIGHUP: case SIGINT: case SIGQUIT: case SIGPIPE: case SIGTERM: exit( 5 ); case SIGCHLD: child = waitpid( snoopedPid, &status, WNOHANG ); if ((child > 0) && WIFEXITED( status )) { snoopStream << endl << endl << "SIGCHLD: WEXITSTATUS==" << WEXITSTATUS(status) << ": " << tttraceCmd.str().c_str() << endl << endl; } break; case SIGCONT: break; } } #if !defined(SIG_PF) typedef void (*sig_pf_t)(int); #define SIG_PF sig_pf_t #endif int _tt_sigset( int sig, SIG_PF handler ) { #if defined(__linux__) || defined(CSRG_BASED) struct sigaction act; act.sa_handler = handler; sigemptyset(&act.sa_mask); act.sa_flags = 0; return 0==sigaction(sig, &act, NULL); #elif defined(OPT_BSD_SIGNAL) return SIG_ERR!=signal(sig, handler); #else return SIG_ERR!=sigset(sig, handler); #endif } static void installSignalHandler() { _tt_sigset( SIGHUP, signalHandler ); _tt_sigset( SIGINT, signalHandler ); _tt_sigset( SIGQUIT, signalHandler ); _tt_sigset( SIGPIPE, signalHandler ); _tt_sigset( SIGTERM, signalHandler ); _tt_sigset( SIGCHLD, signalHandler ); _tt_sigset( SIGCONT, signalHandler ); atexit( cleanUp ); } void snoopIt( const char *callBackType, void *callBack, Tt_message msg, Tt_pattern pat, Boolean printPat ) { if (snoopStream.bad()) { return; } char timeBuf[ 16 ]; time_t now = time( 0 ); strftime( timeBuf, sizeof( timeBuf ), "%T", localtime( &now )); snoopStream << timeBuf << " (" << callBackType << ")" << callBack; snoopStream << "( " << "(Tt_message)" << (void *)msg << ", "; if (printPat) { snoopStream << "(Tt_pattern)" << (void *)pat; } else { snoopStream << "..."; } snoopStream << " ): "; char *msgString = tt_message_print( msg ); Tt_status status = tt_ptr_error( msgString ); if (status == TT_OK) { snoopStream << endl << msgString << endl; } else { snoopStream << status << endl; } tt_free( msgString ); } static Tt_callback_action justSnoopIt( Tt_message msg, Tt_pattern pat ) { DtTtCreated( DTTT_MESSAGE, msg ); // XXX bad idea? snoopIt( "Tt_callback_action", (void *) justSnoopIt, msg, pat, True ); return TT_CALLBACK_PROCESSED; } Tt_message _DtTtMediaLoadPatCb( Tt_message msg, void *clientdata, Tttk_op op, Tt_status diagnosis, unsigned char *contents, int len, char *file, char *docname ) { tt_free( (caddr_t)contents ); tt_free( file ); tt_free( docname ); snoopIt( "Ttmedia_load_pat_cb", (void *) _DtTtMediaLoadPatCb, msg ); return 0; } /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ /* * command line options... */ static XrmOptionDescRec optionDescList[] = { {"-session", "*session", XrmoptionSepArg, (XPointer)NULL} /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/ }; /* * Application Resources */ static XtResource resources[] = { {"session", "Session", XtRString, sizeof(String), XtOffsetOf(DtbAppResourceRec, session_file), XtRImmediate, (XtPointer)NULL} /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/ /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/ }; DtbAppResourceRec dtb_app_resource_rec; /* * main for application ttsnoop */ int main(int argc, char **argv) { Widget toplevel = NULL; Display *display = NULL; XtAppContext app; Atom save_yourself_atom; Pixmap icon_pixmap = 0; Pixmap icon_mask_pixmap = 0; /************************************************************************** *** DTB_USER_CODE_START *** *** No initialization has been done. *** *** Add local variables and code. ***/ /* * The application must call DtTermInitialize() before * initializing the Xt Toolkit with XtAppInitialize(3X). */ DtTermInitialize(); /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ toplevel = XtVaAppInitialize(&app, "Ttsnoop", optionDescList, XtNumber(optionDescList), &argc, argv, (String *)NULL, (ArgList) NULL, 0); /* * Get display and verify initialization was successful. */ if (toplevel != NULL) { display = XtDisplayOfObject(toplevel); } if (display == NULL) { fprintf(stderr, "Could not open display."); exit(1); } /* * Save the toplevel widget so it can be fetched later as needed. */ dtb_save_toplevel_widget(toplevel); /* * Save the command used to invoke the application. */ dtb_save_command(argv[0]); XtGetApplicationResources(toplevel, (XtPointer)&dtb_app_resource_rec, resources, XtNumber(resources), (Arg *)NULL, 0); /************************************************************************** *** DTB_USER_CODE_START *** *** A connection to the X server has been established, and all *** initialization has been done. *** *** Add extra initialization code after this comment. ***/ /* PixelSet pixels[MAX_NUM_COLORS]; int colorUse; short act, inact, prim, second; XmeGetPixelData( DefaultScreen( display ), &colorUse, pixels, &act, &inact, &prim, &second ); Pixmap pixmap = XmGetPixmap( DefaultScreenOfDisplay( display ), "DtTtsnp.l", pixels[1].fg, pixels[1].bg ); XtVaSetValues( toplevel, XmNiconPixmap, pixmap, NULL) ; pixmap = XmeGetMask( XtScreen( toplevel ), "DtTtsnp.l" ); XtVaSetValues( toplevel, XmNiconMask, pixmap, NULL) ; */ Boolean committed2Snooping = False; int c; while ((c = getopt(argc, argv, "?F:<:v:nNe:TuS:Xw:l:o:O:")) != -1) { switch (c) { case 'F': if (! optImmediateSnooping) { clog << Usage; exit( 2 ); } committed2Snooping = 1; listAppend( scopeFiles, scopeFilesCount, char *, optarg ); break; case '<': if (! optImmediateSnooping) { clog << Usage; exit( 2 ); } committed2Snooping = 1; listAppend( senders, sendersCount, char *, optarg ); break; case 'v': if ((! optImmediateSnooping) || (vtype != 0)) { clog << Usage; exit( 2 ); } committed2Snooping = 1; vtype = optarg; break; case 'm': if (! optImmediateSnooping) { clog << Usage; exit( 2 ); } committed2Snooping = 1; listAppend( ops, opsCount, char *, optarg ); break; case 'n': if (committed2Snooping) { clog << Usage; exit( 2 ); } optImmediateSnooping = False; break; case 'N': if (committed2Snooping) { clog << Usage; exit( 2 ); } optImmediateSnooping = False; optImmediateTtOpen = False; break; case 'e': optTraceScript = optarg; break; case 'T': optImmediateTracing = True; break; case 'u': optMapOnOutput = True; break; case 'S': if (optImmediateSession != 0) { clog << Usage; exit( 2 ); } optImmediateSession = optarg; break; case 'X': if (optImmediateSession != 0) { clog << Usage; exit( 2 ); } optImmediateXSession = True; break; case 'w': globalTimeout = atoi( optarg ); if (globalTimeout > 0) { globalTimeout *= 1000; } break; case 'l': globalSaveLines = atoi( optarg ); break; case 'o': if (snoopFile != 0) { clog << Usage; exit( 2 ); } snoopFile = optarg; unlinkSnoopFile = False; break; case 'O': if (traceFile != 0) { clog << Usage; exit( 2 ); } traceFile = optarg; unlinkTraceFile = False; break; case '?': default: clog << Usage; exit( 2 ); } } installSignalHandler(); if (traceFile == 0) { // // Set up fifo for trace output // traceFile = tempnam( 0, "ttsnt" ); if (mkfifo( traceFile, S_IWUSR | S_IRUSR ) == -1) { clog << "ttsnoop: mkfifo( \"" << traceFile << "\" ) = "; clog << strerror( errno ) << endl; } } apiTracerArgv[ 0 ] = "tail"; apiTracerArgv[ 1 ] = "-n"; apiTracerArgv[ 2 ] = "+0"; apiTracerArgv[ 3 ] = "-f"; apiTracerArgv[ 4 ] = traceFile; if (snoopFile == 0) { // // Set up fifo for snoop output // snoopFile = tempnam( 0, "ttsnp" ); if (mkfifo( snoopFile, S_IWUSR | S_IRUSR ) == -1) { clog << "ttsnoop: mkfifo( \"" << snoopFile << "\" ) = "; clog << strerror( errno ) << endl; } } snooperArgv[ 0 ] = "tail"; snooperArgv[ 1 ] = "-n"; snooperArgv[ 2 ] = "+0"; snooperArgv[ 3 ] = "-f"; snooperArgv[ 4 ] = snoopFile; if (optind < argc) { if (committed2Snooping) { clog << Usage; exit( 2 ); } optImmediateSnooping = False; optImmediateTtOpen = False; listAppend( snoopedArgs, snoopedArgsCount, char *, "tttrace" ); listAppend( snoopedArgs, snoopedArgsCount, char *, "-o" ); listAppend( snoopedArgs, snoopedArgsCount, char *, snoopFile ); tttraceCmd << "tttrace -o " << snoopFile; if (optTraceScript != 0) { listAppend( snoopedArgs, snoopedArgsCount, char *, "-e" ); listAppend( snoopedArgs, snoopedArgsCount, char *, optTraceScript ); tttraceCmd << " -e \"" << optTraceScript << "\""; } for (int i = optind; i < argc; i++) { listAppend( snoopedArgs, snoopedArgsCount, char *, argv[i] ); tttraceCmd << " " << argv[i]; } tttraceCmd << ends; listAppend( snoopedArgs, snoopedArgsCount, char *, 0 ); } #if defined(aix) #define AIX_STRING_LIST (char * const *) #else #define AIX_STRING_LIST #endif if (snoopedArgsCount > 0) { snoopedPid = fork(); switch (snoopedPid) { case -1: clog << "ttsnoop: fork(): " << strerror( errno ) << endl; exit( 3 ); case 0: execvp( snoopedArgs[0], AIX_STRING_LIST snoopedArgs ); clog << "ttsnoop: execvp(): " << strerror( errno ) << endl; exit( 3 ); } installSignalHandler(); } /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ /* * Initialize all global variables. */ dtbTtsnoopTtsnoopWinInfo_clear(&dtb_ttsnoop_ttsnoop_win); dtbApiTracerTracerInfo_clear(&dtb_api_tracer_tracer); dtbTtChooserChooserInfo_clear(&dtb_tt_chooser_chooser); dtbPatternPropsPatternPropsInfo_clear(&dtb_pattern_props_pattern_props); dtbStringChooserStringChooserInfo_clear(&dtb_string_chooser_string_chooser); dtbMessagePropsMessagePropsInfo_clear(&dtb_message_props_message_props); dtbSessionChooserSessionChooserInfo_clear(&dtb_session_chooser_session_chooser); dtbFileChooserFchooserInfo_clear(&dtb_file_chooser_fchooser); dtbArgChooserArgChooserInfo_clear(&dtb_arg_chooser_arg_chooser); dtbCallbackChooserCallbackChooserInfo_clear(&dtb_callback_chooser_callback_chooser); /* * Set up the application's root window. */ dtb_ttsnoop_ttsnoop_win.ttsnoopWin = toplevel; dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "DtTtsnp.l", &icon_pixmap); dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "DtTtsnp.l_m", &icon_mask_pixmap); XtVaSetValues(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, XmNallowShellResize, True, XmNtitle, "ttsnoop", XmNiconMask, icon_mask_pixmap, XmNiconPixmap, icon_pixmap, XmNbackground, dtb_cvt_string_to_pixel(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "white"), NULL); dtb_ttsnoop_ttsnoop_win_initialize(&(dtb_ttsnoop_ttsnoop_win), dtb_get_toplevel_widget()); /* * Map any initially-visible windows */ save_yourself_atom = XmInternAtom(XtDisplay(toplevel), "WM_SAVE_YOURSELF", False); dtb_set_client_session_saveCB((DtbClientSessionSaveCB)NULL); XmAddWMProtocolCallback(toplevel, save_yourself_atom, dtb_session_save, (XtPointer)NULL); /************************************************************************** *** DTB_USER_CODE_START *** *** All initially-mapped widgets have been created, but not *** realized. Set resources on widgets, or perform other operations *** that must be completed before the toplevel widget is *** realized. ***/ /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ XtRealizeWidget(toplevel); /************************************************************************** *** DTB_USER_CODE_START *** *** The initially-mapped widgets have all been realized, and *** the Xt main loop is about to be entered. ***/ installSignalHandler(); if (snoopedArgsCount > 0) { DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label, tttraceCmd.str().c_str() ); } Tt_status status; snoopStream.open( snoopFile, ios::app ); std::ostringstream envStr; envStr << "TT_TRACE_SCRIPT=> "; envStr << traceFile << ends; traceScript = envStr.str(); if (optImmediateTracing) { turnOnTracing( 0, 0, 0 ); } if (optImmediateXSession) { char *display = getenv( "DISPLAY" ); optImmediateSession = tt_X_session( display ); status = tt_ptr_error( optImmediateSession ); if (tt_is_err( status )) { clog << "ttsnoop: tt_X_session( "; if (display == 0) { clog << "0"; } else { clog << "\"" << display << "\""; } clog << " ) = " << (void *)optImmediateSession; clog << " (" << status << ")" << endl; exit( 4 ); } } if (optImmediateSession != 0) { status = tt_default_session_set( optImmediateSession ); if (tt_is_err( status )) { clog << "ttsnoop: tt_default_session_set( \""; clog << optImmediateSession << "\" ) = "; clog << status << endl; exit( 4 ); } } if (optImmediateTtOpen) { int fd; char *procid = ttdt_open( &fd, "Ttsnoop", "CDE", globalVersionString, 1 ); DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label, "ttdt_open()", procid ); status = tt_ptr_error( procid ); if (tt_is_err( status )) { char *statmsg = tt_status_message(status); clog << "ttsnoop: ttdt_open() = "; clog << status << ": " << statmsg << endl; exit( 4 ); } XtInputId id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask, tttk_Xt_input_handler, procid ); DtTtCreated( DTTT_PROCID, procid, (void *)id ); if (optImmediateSnooping) { Tt_pattern pat = tt_pattern_create(); tt_pattern_category_set( pat, TT_OBSERVE ); if (scopeFilesCount > 0) { tt_pattern_scope_add( pat, TT_BOTH ); for (int i = 0; i < scopeFilesCount; i++) { tt_pattern_file_add( pat, scopeFiles[i] ); } } else { tt_pattern_scope_add( pat, TT_SESSION ); } char *sess = tt_default_session(); tt_pattern_session_add( pat, sess ); tt_free( sess ); for (int i = 0; i < opsCount; i++) { tt_pattern_op_add( pat, ops[i] ); } for (int i = 0; i < sendersCount; i++) { tt_pattern_sender_add( pat, senders[i] ); } if (vtype != 0) { tt_pattern_arg_add( pat, TT_MODE_UNDEFINED, vtype, 0 ); } tt_pattern_callback_add( pat, justSnoopIt ); status = tt_pattern_register( pat ); DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label, "tt_pattern_register()", pat ); if (tt_is_err( status )) { char *statmsg = tt_status_message(status); clog << "ttsnoop: tt_pattern_register() = "; clog << status << ": " << statmsg << endl; exit( 4 ); } DtTtCreated( DTTT_PATTERN, pat ); snoopPat = pat; snoopPatIsRegistered = True; } } if (snoopPat == 0) { XtSetSensitive( dtb_ttsnoop_ttsnoop_win. menubar_Snoop_item_Snoop_menu_items.Off_item, False ); } DtTtSetLabel( dtb_ttsnoop_ttsnoop_win. menubar_Snoop_item_Snoop_menu_items.Off_item, snoopPatIsRegistered ? "Off" : "On" ); if (optMapOnOutput) { XtVaSetValues( dtb_ttsnoop_ttsnoop_win.ttsnoopPane, DtNmapOnOutput, optMapOnOutput, NULL ); } installSignalHandler(); /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/ /* * Enter event loop */ XtAppMainLoop(app); exit(0); } /************************************************************************** *** DTB_USER_CODE_START *** *** All automatically-generated data and functions have been defined. *** *** Add new functions here, or at the top of the file. ***/ /*** DTB_USER_CODE_END *** *** End of user code section *** **************************************************************************/