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 std::string traceScript;
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 ] = "-n";
521 apiTracerArgv[ 2 ] = "+0";
522 apiTracerArgv[ 3 ] = "-f";
523 apiTracerArgv[ 4 ] = traceFile;
524 if (snoopFile == 0) {
526 // Set up fifo for snoop output
528 snoopFile = tempnam( 0, "ttsnp" );
529 if (mkfifo( snoopFile, S_IWUSR | S_IRUSR ) == -1) {
530 clog << "ttsnoop: mkfifo( \"" << snoopFile << "\" ) = ";
531 clog << strerror( errno ) << endl;
534 snooperArgv[ 0 ] = "tail";
535 snooperArgv[ 1 ] = "-n";
536 snooperArgv[ 2 ] = "+0";
537 snooperArgv[ 3 ] = "-f";
538 snooperArgv[ 4 ] = snoopFile;
541 if (committed2Snooping) {
542 clog << Usage; exit( 2 );
544 optImmediateSnooping = False;
545 optImmediateTtOpen = False;
546 listAppend( snoopedArgs, snoopedArgsCount, char *, "tttrace" );
547 listAppend( snoopedArgs, snoopedArgsCount, char *, "-o" );
548 listAppend( snoopedArgs, snoopedArgsCount, char *, snoopFile );
549 tttraceCmd << "tttrace -o " << snoopFile;
550 if (optTraceScript != 0) {
551 listAppend( snoopedArgs, snoopedArgsCount, char *, "-e" );
552 listAppend( snoopedArgs, snoopedArgsCount, char *,
554 tttraceCmd << " -e \"" << optTraceScript << "\"";
556 for (int i = optind; i < argc; i++) {
557 listAppend( snoopedArgs, snoopedArgsCount, char *,
559 tttraceCmd << " " << argv[i];
562 listAppend( snoopedArgs, snoopedArgsCount, char *, 0 );
566 #define AIX_STRING_LIST (char * const *)
568 #define AIX_STRING_LIST
571 if (snoopedArgsCount > 0) {
573 switch (snoopedPid) {
575 clog << "ttsnoop: fork(): " << strerror( errno ) << endl;
578 execvp( snoopedArgs[0], AIX_STRING_LIST snoopedArgs );
579 clog << "ttsnoop: execvp(): " << strerror( errno ) << endl;
582 installSignalHandler();
585 /*** DTB_USER_CODE_END
587 *** End of user code section
589 **************************************************************************/
594 * Initialize all global variables.
596 dtbTtsnoopTtsnoopWinInfo_clear(&dtb_ttsnoop_ttsnoop_win);
597 dtbApiTracerTracerInfo_clear(&dtb_api_tracer_tracer);
598 dtbTtChooserChooserInfo_clear(&dtb_tt_chooser_chooser);
599 dtbPatternPropsPatternPropsInfo_clear(&dtb_pattern_props_pattern_props);
600 dtbStringChooserStringChooserInfo_clear(&dtb_string_chooser_string_chooser);
601 dtbMessagePropsMessagePropsInfo_clear(&dtb_message_props_message_props);
602 dtbSessionChooserSessionChooserInfo_clear(&dtb_session_chooser_session_chooser);
603 dtbFileChooserFchooserInfo_clear(&dtb_file_chooser_fchooser);
604 dtbArgChooserArgChooserInfo_clear(&dtb_arg_chooser_arg_chooser);
605 dtbCallbackChooserCallbackChooserInfo_clear(&dtb_callback_chooser_callback_chooser);
608 * Set up the application's root window.
610 dtb_ttsnoop_ttsnoop_win.ttsnoopWin = toplevel;
611 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
612 "DtTtsnp.l", &icon_pixmap);
613 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
614 "DtTtsnp.l_m", &icon_mask_pixmap);
615 XtVaSetValues(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
616 XmNallowShellResize, True,
618 XmNiconMask, icon_mask_pixmap,
619 XmNiconPixmap, icon_pixmap,
620 XmNbackground, dtb_cvt_string_to_pixel(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "white"),
623 dtb_ttsnoop_ttsnoop_win_initialize(&(dtb_ttsnoop_ttsnoop_win), dtb_get_toplevel_widget());
626 * Map any initially-visible windows
629 save_yourself_atom = XmInternAtom(XtDisplay(toplevel),
630 "WM_SAVE_YOURSELF", False);
632 dtb_set_client_session_saveCB((DtbClientSessionSaveCB)NULL);
634 XmAddWMProtocolCallback(toplevel, save_yourself_atom,
635 dtb_session_save, (XtPointer)NULL);
638 /**************************************************************************
639 *** DTB_USER_CODE_START
641 *** All initially-mapped widgets have been created, but not
642 *** realized. Set resources on widgets, or perform other operations
643 *** that must be completed before the toplevel widget is
647 /*** DTB_USER_CODE_END
649 *** End of user code section
651 **************************************************************************/
654 XtRealizeWidget(toplevel);
657 /**************************************************************************
658 *** DTB_USER_CODE_START
660 *** The initially-mapped widgets have all been realized, and
661 *** the Xt main loop is about to be entered.
664 installSignalHandler();
665 if (snoopedArgsCount > 0) {
666 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
667 tttraceCmd.str().c_str() );
670 snoopStream.open( snoopFile, ios::app );
671 std::ostringstream envStr;
672 envStr << "TT_TRACE_SCRIPT=> ";
673 envStr << traceFile << ends;
674 traceScript = envStr.str();
675 if (optImmediateTracing) {
676 turnOnTracing( 0, 0, 0 );
678 if (optImmediateXSession) {
679 char *display = getenv( "DISPLAY" );
680 optImmediateSession = tt_X_session( display );
681 status = tt_ptr_error( optImmediateSession );
682 if (tt_is_err( status )) {
683 clog << "ttsnoop: tt_X_session( ";
687 clog << "\"" << display << "\"";
689 clog << " ) = " << (void *)optImmediateSession;
690 clog << " (" << status << ")" << endl;
694 if (optImmediateSession != 0) {
695 status = tt_default_session_set( optImmediateSession );
696 if (tt_is_err( status )) {
697 clog << "ttsnoop: tt_default_session_set( \"";
698 clog << optImmediateSession << "\" ) = ";
699 clog << status << endl;
703 if (optImmediateTtOpen) {
705 char *procid = ttdt_open( &fd, "Ttsnoop", "CDE",
706 globalVersionString, 1 );
707 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
708 "ttdt_open()", procid );
709 status = tt_ptr_error( procid );
710 if (tt_is_err( status )) {
711 char *statmsg = tt_status_message(status);
712 clog << "ttsnoop: ttdt_open() = ";
713 clog << status << ": " << statmsg << endl;
716 XtInputId id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask,
717 tttk_Xt_input_handler, procid );
718 DtTtCreated( DTTT_PROCID, procid, (void *)id );
719 if (optImmediateSnooping) {
720 Tt_pattern pat = tt_pattern_create();
721 tt_pattern_category_set( pat, TT_OBSERVE );
722 if (scopeFilesCount > 0) {
723 tt_pattern_scope_add( pat, TT_BOTH );
724 for (int i = 0; i < scopeFilesCount; i++) {
725 tt_pattern_file_add( pat, scopeFiles[i] );
728 tt_pattern_scope_add( pat, TT_SESSION );
730 char *sess = tt_default_session();
731 tt_pattern_session_add( pat, sess );
733 for (int i = 0; i < opsCount; i++) {
734 tt_pattern_op_add( pat, ops[i] );
736 for (int i = 0; i < sendersCount; i++) {
737 tt_pattern_sender_add( pat, senders[i] );
740 tt_pattern_arg_add( pat, TT_MODE_UNDEFINED,
743 tt_pattern_callback_add( pat, justSnoopIt );
744 status = tt_pattern_register( pat );
745 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
746 "tt_pattern_register()", pat );
747 if (tt_is_err( status )) {
748 char *statmsg = tt_status_message(status);
749 clog << "ttsnoop: tt_pattern_register() = ";
750 clog << status << ": " << statmsg << endl;
753 DtTtCreated( DTTT_PATTERN, pat );
755 snoopPatIsRegistered = True;
759 XtSetSensitive( dtb_ttsnoop_ttsnoop_win.
760 menubar_Snoop_item_Snoop_menu_items.Off_item, False );
762 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.
763 menubar_Snoop_item_Snoop_menu_items.Off_item,
764 snoopPatIsRegistered ? "Off" : "On" );
765 if (optMapOnOutput) {
766 XtVaSetValues( dtb_ttsnoop_ttsnoop_win.ttsnoopPane,
767 DtNmapOnOutput, optMapOnOutput, NULL );
769 installSignalHandler();
771 /*** DTB_USER_CODE_END
773 *** End of user code section
775 **************************************************************************/
787 /**************************************************************************
788 *** DTB_USER_CODE_START
790 *** All automatically-generated data and functions have been defined.
792 *** Add new functions here, or at the top of the file.
795 /*** DTB_USER_CODE_END
797 *** End of user code section
799 **************************************************************************/