1 /*** DTB_USER_CODE_START vvv Add file header below vvv ***/
2 /* $TOG: ttsnoop.C.src /main/8 1999/09/20 16:07:27 mgreess $ */
3 /*** DTB_USER_CODE_END ^^^ Add file header above ^^^ ***/
7 * Contains: main() and cross-module connections
9 * This file was generated by dtcodegen, from project ttsnoop
11 * Any text may be added between the DTB_USER_CODE_START and
12 * DTB_USER_CODE_END comments (even non-C code). Descriptive comments
13 * are provided only as an aid.
15 * ** EDIT ONLY WITHIN SECTIONS MARKED WITH DTB_USER_CODE COMMENTS. **
16 * ** ALL OTHER MODIFICATIONS WILL BE OVERWRITTEN. DO NOT MODIFY OR **
17 * ** DELETE THE GENERATED COMMENTS! **
23 #include <sys/param.h>
24 #include <sys/types.h>
25 #include <sys/types.h>
27 #include <X11/Intrinsic.h>
29 #include <Xm/MwmUtil.h>
30 #include <Xm/Protocols.h>
32 #include <Dt/HelpQuickD.h>
33 #include <Dt/HelpDialog.h>
35 #include <Dt/Session.h>
37 #include "ttsnoop_ui.h"
38 #include "apiTracer_ui.h"
39 #include "ttChooser_ui.h"
40 #include "patternProps_ui.h"
41 #include "stringChooser_ui.h"
42 #include "messageProps_ui.h"
43 #include "sessionChooser_ui.h"
44 #include "fileChooser_ui.h"
45 #include "argChooser_ui.h"
46 #include "callbackChooser_ui.h"
48 #include "dtb_utils.h"
51 /**************************************************************************
52 *** DTB_USER_CODE_START
54 *** All necessary header files have been included.
56 *** Add include files, types, macros, externs, and user functions here.
76 //#include <Xm/ColorObj.h>
77 //#include <Xm/ColorObjP.h>
78 //extern "C" { Pixmap XmeGetMask( Screen *, const char * ); }
80 Boolean optImmediateTracing = False;
81 Boolean optMapOnOutput = False;
82 Boolean optImmediateSnooping = True;
83 Boolean optImmediateTtOpen = True;
84 Boolean optImmediateXSession = False;
85 char * optImmediateSession = 0;
86 Tt_pattern snoopPat = 0;
87 Boolean snoopPatIsRegistered = False;
89 Boolean unlinkSnoopFile = True;
91 Boolean unlinkTraceFile = True;
92 const char * traceScript = 0;
93 int globalTimeout = 20000;
94 unsigned int globalSaveLines = 5000;
95 const char * globalVersionString = "1.0";
96 char ** scopeFiles = 0;
97 unsigned int scopeFilesCount = 0;
99 unsigned int opsCount = 0;
101 unsigned int sendersCount = 0;
103 pid_t snoopedPid = -1;
104 char ** snoopedArgs = 0;
105 unsigned int snoopedArgsCount = 0;
106 char * optTraceScript = 0;
107 String apiTracerArgv[ 10 ];
108 String snooperArgv[ 10 ];
109 std::ostringstream tttraceCmd;
110 std::ofstream snoopStream;
112 // Xt squats on -tf ?! XXX
114 "ttsnoop - ToolTalk graphical user interface\n"
115 "Usage: ttsnoop [options] [-F scopefile] [-< procid] [-v media] [-m op]\n"
116 " ttsnoop [options] -n|-N\n"
117 " ttsnoop [options] [-e script] command [args]\n"
119 "-F scopefile scope initial pattern also to scopefile\n"
120 "-\\< \"procid\" limit initial pattern to messages from procid\n"
121 "-v mediaType limit initial pattern to messages for mediaType\n"
122 "-m op limit initial pattern to given op\n"
124 "-n skip initial pattern\n"
125 "-N skip initial ttdt_open(), also\n"
127 "command [args] invoke command [with args] and snoop its TT API calls\n"
128 "-e script Take script as a tttrace setting. See tttracefile(4).\n"
130 "options ::= [-Tu] [-S sessid] [-w n] [-l n] [-o snoopfile] [-O tracefile]\n"
131 "-T trace (even initial) TT API calls made by ttsnoop\n"
132 "-u map (de-iconify) on snoop output\n"
133 "-S sessid set default session to sessid\n"
134 "-X set default session to tt_X_session of $DISPLAY\n"
135 "-w n set global timeout to n seconds [default: 20]\n"
136 "-l n set tttrace dtterm saveLines to n lines [default: 5000]\n"
137 "-o snoopfile log snoop output to snoopfile\n"
138 "-O tracefile log api tracing to tracefile\n"
140 "-xrm \"*DtTerm.saveLines: n\"\n"
141 "-xrm \"*DtTerm.rows: n\"\n"
142 "-xrm \"*DtTerm.columns: n\"\n"
143 "-xrm \"*DtTerm.mapOnOutput: true\"\n";
148 if (unlinkSnoopFile) {
149 if (unlink( snoopFile ) == -1) {
150 clog << "ttsnoop: unlink( \"" << snoopFile;
151 clog << "\"): " << strerror( errno ) << endl;
153 unlinkSnoopFile = False;
156 if (unlinkTraceFile) {
157 if (unlink( traceFile ) == -1) {
158 clog << "ttsnoop: unlink( \"" << traceFile;
159 clog << "\"): " << strerror( errno ) << endl;
161 unlinkTraceFile = False;
181 child = waitpid( snoopedPid, &status, WNOHANG );
182 if ((child > 0) && WIFEXITED( status )) {
183 snoopStream << endl << endl << "SIGCHLD: WEXITSTATUS=="
184 << WEXITSTATUS(status) << ": "
185 << tttraceCmd.str().c_str() << endl << endl;
193 #if defined(SVR4) || defined(aix) || defined(hpux) || defined(__linux__) || defined(CSRG_BASED)
195 typedef void (*sig_pf_t)(int);
196 #define SIG_PF sig_pf_t
205 #if defined(hpux) || defined(__linux__) || defined(CSRG_BASED)
206 struct sigaction act;
207 act.sa_handler = handler;
208 sigemptyset(&act.sa_mask);
210 return 0==sigaction(sig, &act, NULL);
211 #elif defined(OPT_BSD_SIGNAL)
212 return SIG_ERR!=signal(sig, handler);
214 return SIG_ERR!=sigset(sig, handler);
219 installSignalHandler()
221 _tt_sigset( SIGHUP, signalHandler );
222 _tt_sigset( SIGINT, signalHandler );
223 _tt_sigset( SIGQUIT, signalHandler );
224 _tt_sigset( SIGPIPE, signalHandler );
225 _tt_sigset( SIGTERM, signalHandler );
226 _tt_sigset( SIGCHLD, signalHandler );
227 _tt_sigset( SIGCONT, signalHandler );
233 const char *callBackType,
240 if (snoopStream.bad()) {
244 time_t now = time( 0 );
245 strftime( timeBuf, sizeof( timeBuf ), "%T", localtime( &now ));
246 snoopStream << timeBuf << " (" << callBackType << ")" << callBack;
247 snoopStream << "( " << "(Tt_message)" << (void *)msg << ", ";
249 snoopStream << "(Tt_pattern)" << (void *)pat;
251 snoopStream << "...";
253 snoopStream << " ): ";
254 char *msgString = tt_message_print( msg );
255 Tt_status status = tt_ptr_error( msgString );
256 if (status == TT_OK) {
257 snoopStream << endl << msgString << endl;
259 snoopStream << status << endl;
261 tt_free( msgString );
264 static Tt_callback_action
270 DtTtCreated( DTTT_MESSAGE, msg ); // XXX bad idea?
271 snoopIt( "Tt_callback_action", (void *) justSnoopIt, msg, pat, True );
272 return TT_CALLBACK_PROCESSED;
281 unsigned char *contents,
287 tt_free( (caddr_t)contents );
290 snoopIt( "Ttmedia_load_pat_cb", (void *) _DtTtMediaLoadPatCb, msg );
294 /*** DTB_USER_CODE_END
296 *** End of user code section
298 **************************************************************************/
303 * command line options...
305 static XrmOptionDescRec optionDescList[] = {
306 {"-session", "*session", XrmoptionSepArg, (XPointer)NULL}
308 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
309 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
313 * Application Resources
315 static XtResource resources[] = {
316 {"session", "Session", XtRString, sizeof(String),
317 XtOffsetOf(DtbAppResourceRec, session_file), XtRImmediate, (XtPointer)NULL}
319 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
320 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
323 DtbAppResourceRec dtb_app_resource_rec;
327 * main for application ttsnoop
330 main(int argc, char **argv)
332 Widget toplevel = NULL;
333 Display *display = NULL;
335 Atom save_yourself_atom;
337 Pixmap icon_pixmap = 0;
338 Pixmap icon_mask_pixmap = 0;
340 /**************************************************************************
341 *** DTB_USER_CODE_START
343 *** No initialization has been done.
345 *** Add local variables and code.
349 * The application must call DtTermInitialize() before
350 * initializing the Xt Toolkit with XtAppInitialize(3X).
354 /*** DTB_USER_CODE_END
356 *** End of user code section
358 **************************************************************************/
360 toplevel = XtVaAppInitialize(&app, "Ttsnoop",
361 optionDescList, XtNumber(optionDescList),
362 &argc, argv, (String *)NULL,
366 * Get display and verify initialization was successful.
368 if (toplevel != NULL)
370 display = XtDisplayOfObject(toplevel);
374 fprintf(stderr, "Could not open display.");
379 * Save the toplevel widget so it can be fetched later as needed.
381 dtb_save_toplevel_widget(toplevel);
384 * Save the command used to invoke the application.
386 dtb_save_command(argv[0]);
388 XtGetApplicationResources(toplevel, (XtPointer)&dtb_app_resource_rec,
389 resources, XtNumber(resources), (Arg *)NULL, 0);
392 /**************************************************************************
393 *** DTB_USER_CODE_START
395 *** A connection to the X server has been established, and all
396 *** initialization has been done.
398 *** Add extra initialization code after this comment.
402 PixelSet pixels[MAX_NUM_COLORS];
404 short act, inact, prim, second;
405 XmeGetPixelData( DefaultScreen( display ), &colorUse, pixels,
406 &act, &inact, &prim, &second );
407 Pixmap pixmap = XmGetPixmap( DefaultScreenOfDisplay( display ),
408 "DtTtsnp.l", pixels[1].fg, pixels[1].bg );
409 XtVaSetValues( toplevel, XmNiconPixmap, pixmap, NULL) ;
410 pixmap = XmeGetMask( XtScreen( toplevel ), "DtTtsnp.l" );
411 XtVaSetValues( toplevel, XmNiconMask, pixmap, NULL) ;
413 Boolean committed2Snooping = False;
415 while ((c = getopt(argc, argv, "?F:<:v:nNe:TuS:Xw:l:o:O:")) != -1) {
418 if (! optImmediateSnooping) {
419 clog << Usage; exit( 2 );
421 committed2Snooping = 1;
422 listAppend( scopeFiles, scopeFilesCount, char *, optarg );
425 if (! optImmediateSnooping) {
426 clog << Usage; exit( 2 );
428 committed2Snooping = 1;
429 listAppend( senders, sendersCount, char *, optarg );
432 if ((! optImmediateSnooping) || (vtype != 0)) {
433 clog << Usage; exit( 2 );
435 committed2Snooping = 1;
439 if (! optImmediateSnooping) {
440 clog << Usage; exit( 2 );
442 committed2Snooping = 1;
443 listAppend( ops, opsCount, char *, optarg );
446 if (committed2Snooping) {
447 clog << Usage; exit( 2 );
449 optImmediateSnooping = False;
452 if (committed2Snooping) {
453 clog << Usage; exit( 2 );
455 optImmediateSnooping = False;
456 optImmediateTtOpen = False;
459 optTraceScript = optarg;
462 optImmediateTracing = True;
465 optMapOnOutput = True;
468 if (optImmediateSession != 0) {
469 clog << Usage; exit( 2 );
471 optImmediateSession = optarg;
474 if (optImmediateSession != 0) {
475 clog << Usage; exit( 2 );
477 optImmediateXSession = True;
480 globalTimeout = atoi( optarg );
481 if (globalTimeout > 0) {
482 globalTimeout *= 1000;
486 globalSaveLines = atoi( optarg );
489 if (snoopFile != 0) {
490 clog << Usage; exit( 2 );
493 unlinkSnoopFile = False;
496 if (traceFile != 0) {
497 clog << Usage; exit( 2 );
500 unlinkTraceFile = False;
504 clog << Usage; exit( 2 );
508 installSignalHandler();
509 if (traceFile == 0) {
511 // Set up fifo for trace output
513 traceFile = tempnam( 0, "ttsnt" );
514 if (mkfifo( traceFile, S_IWUSR | S_IRUSR ) == -1) {
515 clog << "ttsnoop: mkfifo( \"" << traceFile << "\" ) = ";
516 clog << strerror( errno ) << endl;
519 apiTracerArgv[ 0 ] = "tail";
520 apiTracerArgv[ 1 ] = "-f";
521 apiTracerArgv[ 2 ] = traceFile;
522 if (snoopFile == 0) {
524 // Set up fifo for snoop output
526 snoopFile = tempnam( 0, "ttsnp" );
527 if (mkfifo( snoopFile, S_IWUSR | S_IRUSR ) == -1) {
528 clog << "ttsnoop: mkfifo( \"" << snoopFile << "\" ) = ";
529 clog << strerror( errno ) << endl;
532 snooperArgv[ 0 ] = "tail";
533 snooperArgv[ 1 ] = "-f";
534 snooperArgv[ 2 ] = snoopFile;
537 if (committed2Snooping) {
538 clog << Usage; exit( 2 );
540 optImmediateSnooping = False;
541 optImmediateTtOpen = False;
542 listAppend( snoopedArgs, snoopedArgsCount, char *, "tttrace" );
543 listAppend( snoopedArgs, snoopedArgsCount, char *, "-o" );
544 listAppend( snoopedArgs, snoopedArgsCount, char *, snoopFile );
545 tttraceCmd << "tttrace -o " << snoopFile;
546 if (optTraceScript != 0) {
547 listAppend( snoopedArgs, snoopedArgsCount, char *, "-e" );
548 listAppend( snoopedArgs, snoopedArgsCount, char *,
550 tttraceCmd << " -e \"" << optTraceScript << "\"";
552 for (int i = optind; i < argc; i++) {
553 listAppend( snoopedArgs, snoopedArgsCount, char *,
555 tttraceCmd << " " << argv[i];
558 listAppend( snoopedArgs, snoopedArgsCount, char *, 0 );
562 #define AIX_STRING_LIST (char * const *)
564 #define AIX_STRING_LIST
567 if (snoopedArgsCount > 0) {
569 switch (snoopedPid) {
571 clog << "ttsnoop: fork(): " << strerror( errno ) << endl;
574 execvp( snoopedArgs[0], AIX_STRING_LIST snoopedArgs );
575 clog << "ttsnoop: execvp(): " << strerror( errno ) << endl;
578 installSignalHandler();
581 /*** DTB_USER_CODE_END
583 *** End of user code section
585 **************************************************************************/
590 * Initialize all global variables.
592 dtbTtsnoopTtsnoopWinInfo_clear(&dtb_ttsnoop_ttsnoop_win);
593 dtbApiTracerTracerInfo_clear(&dtb_api_tracer_tracer);
594 dtbTtChooserChooserInfo_clear(&dtb_tt_chooser_chooser);
595 dtbPatternPropsPatternPropsInfo_clear(&dtb_pattern_props_pattern_props);
596 dtbStringChooserStringChooserInfo_clear(&dtb_string_chooser_string_chooser);
597 dtbMessagePropsMessagePropsInfo_clear(&dtb_message_props_message_props);
598 dtbSessionChooserSessionChooserInfo_clear(&dtb_session_chooser_session_chooser);
599 dtbFileChooserFchooserInfo_clear(&dtb_file_chooser_fchooser);
600 dtbArgChooserArgChooserInfo_clear(&dtb_arg_chooser_arg_chooser);
601 dtbCallbackChooserCallbackChooserInfo_clear(&dtb_callback_chooser_callback_chooser);
604 * Set up the application's root window.
606 dtb_ttsnoop_ttsnoop_win.ttsnoopWin = toplevel;
607 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
608 "DtTtsnp.l", &icon_pixmap);
609 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
610 "DtTtsnp.l_m", &icon_mask_pixmap);
611 XtVaSetValues(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
612 XmNallowShellResize, True,
614 XmNiconMask, icon_mask_pixmap,
615 XmNiconPixmap, icon_pixmap,
616 XmNbackground, dtb_cvt_string_to_pixel(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "white"),
619 dtb_ttsnoop_ttsnoop_win_initialize(&(dtb_ttsnoop_ttsnoop_win), dtb_get_toplevel_widget());
622 * Map any initially-visible windows
625 save_yourself_atom = XmInternAtom(XtDisplay(toplevel),
626 "WM_SAVE_YOURSELF", False);
628 dtb_set_client_session_saveCB((DtbClientSessionSaveCB)NULL);
630 XmAddWMProtocolCallback(toplevel, save_yourself_atom,
631 dtb_session_save, (XtPointer)NULL);
634 /**************************************************************************
635 *** DTB_USER_CODE_START
637 *** All initially-mapped widgets have been created, but not
638 *** realized. Set resources on widgets, or perform other operations
639 *** that must be completed before the toplevel widget is
643 /*** DTB_USER_CODE_END
645 *** End of user code section
647 **************************************************************************/
650 XtRealizeWidget(toplevel);
653 /**************************************************************************
654 *** DTB_USER_CODE_START
656 *** The initially-mapped widgets have all been realized, and
657 *** the Xt main loop is about to be entered.
660 installSignalHandler();
661 if (snoopedArgsCount > 0) {
662 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
663 tttraceCmd.str().c_str() );
666 snoopStream.open( snoopFile, ios::app );
667 std::ostringstream envStr;
668 envStr << "TT_TRACE_SCRIPT=> ";
669 envStr << traceFile << ends;
670 traceScript = envStr.str().c_str();
671 if (optImmediateTracing) {
672 turnOnTracing( 0, 0, 0 );
674 if (optImmediateXSession) {
675 char *display = getenv( "DISPLAY" );
676 optImmediateSession = tt_X_session( display );
677 status = tt_ptr_error( optImmediateSession );
678 if (tt_is_err( status )) {
679 clog << "ttsnoop: tt_X_session( ";
683 clog << "\"" << display << "\"";
685 clog << " ) = " << (void *)optImmediateSession;
686 clog << " (" << status << ")" << endl;
690 if (optImmediateSession != 0) {
691 status = tt_default_session_set( optImmediateSession );
692 if (tt_is_err( status )) {
693 clog << "ttsnoop: tt_default_session_set( \"";
694 clog << optImmediateSession << "\" ) = ";
695 clog << status << endl;
699 if (optImmediateTtOpen) {
701 char *procid = ttdt_open( &fd, "Ttsnoop", "CDE",
702 globalVersionString, 1 );
703 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
704 "ttdt_open()", procid );
705 status = tt_ptr_error( procid );
706 if (tt_is_err( status )) {
707 char *statmsg = tt_status_message(status);
708 clog << "ttsnoop: ttdt_open() = ";
709 clog << status << ": " << statmsg << endl;
712 XtInputId id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask,
713 tttk_Xt_input_handler, procid );
714 DtTtCreated( DTTT_PROCID, procid, (void *)id );
715 if (optImmediateSnooping) {
716 Tt_pattern pat = tt_pattern_create();
717 tt_pattern_category_set( pat, TT_OBSERVE );
718 if (scopeFilesCount > 0) {
719 tt_pattern_scope_add( pat, TT_BOTH );
720 for (int i = 0; i < scopeFilesCount; i++) {
721 tt_pattern_file_add( pat, scopeFiles[i] );
724 tt_pattern_scope_add( pat, TT_SESSION );
726 char *sess = tt_default_session();
727 tt_pattern_session_add( pat, sess );
729 for (int i = 0; i < opsCount; i++) {
730 tt_pattern_op_add( pat, ops[i] );
732 for (int i = 0; i < sendersCount; i++) {
733 tt_pattern_sender_add( pat, senders[i] );
736 tt_pattern_arg_add( pat, TT_MODE_UNDEFINED,
739 tt_pattern_callback_add( pat, justSnoopIt );
740 status = tt_pattern_register( pat );
741 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
742 "tt_pattern_register()", pat );
743 if (tt_is_err( status )) {
744 char *statmsg = tt_status_message(status);
745 clog << "ttsnoop: tt_pattern_register() = ";
746 clog << status << ": " << statmsg << endl;
749 DtTtCreated( DTTT_PATTERN, pat );
751 snoopPatIsRegistered = True;
755 XtSetSensitive( dtb_ttsnoop_ttsnoop_win.
756 menubar_Snoop_item_Snoop_menu_items.Off_item, False );
758 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.
759 menubar_Snoop_item_Snoop_menu_items.Off_item,
760 snoopPatIsRegistered ? "Off" : "On" );
761 if (optMapOnOutput) {
762 XtVaSetValues( dtb_ttsnoop_ttsnoop_win.ttsnoopPane,
763 DtNmapOnOutput, optMapOnOutput, NULL );
765 installSignalHandler();
767 /*** DTB_USER_CODE_END
769 *** End of user code section
771 **************************************************************************/
783 /**************************************************************************
784 *** DTB_USER_CODE_START
786 *** All automatically-generated data and functions have been defined.
788 *** Add new functions here, or at the top of the file.
791 /*** DTB_USER_CODE_END
793 *** End of user code section
795 **************************************************************************/