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.
66 #include <strstream.h>
74 //#include <Xm/ColorObj.h>
75 //#include <Xm/ColorObjP.h>
76 //extern "C" { Pixmap XmeGetMask( Screen *, const char * ); }
78 Boolean optImmediateTracing = False;
79 Boolean optMapOnOutput = False;
80 Boolean optImmediateSnooping = True;
81 Boolean optImmediateTtOpen = True;
82 Boolean optImmediateXSession = False;
83 char * optImmediateSession = 0;
84 Tt_pattern snoopPat = 0;
85 Boolean snoopPatIsRegistered = False;
87 Boolean unlinkSnoopFile = True;
89 Boolean unlinkTraceFile = True;
90 char * traceScript = 0;
91 int globalTimeout = 20000;
92 unsigned int globalSaveLines = 5000;
93 const char * globalVersionString = "1.0";
94 char ** scopeFiles = 0;
95 unsigned int scopeFilesCount = 0;
97 unsigned int opsCount = 0;
99 unsigned int sendersCount = 0;
101 pid_t snoopedPid = -1;
102 char ** snoopedArgs = 0;
103 unsigned int snoopedArgsCount = 0;
104 char * optTraceScript = 0;
105 String apiTracerArgv[ 10 ];
106 String snooperArgv[ 10 ];
107 ostrstream tttraceCmd;
108 ofstream snoopStream;
110 // Xt squats on -tf ?! XXX
112 "ttsnoop - ToolTalk graphical user interface\n"
113 "Usage: ttsnoop [options] [-F scopefile] [-< procid] [-v media] [-m op]\n"
114 " ttsnoop [options] -n|-N\n"
115 " ttsnoop [options] [-e script] command [args]\n"
117 "-F scopefile scope initial pattern also to scopefile\n"
118 "-\\< \"procid\" limit initial pattern to messages from procid\n"
119 "-v mediaType limit initial pattern to messages for mediaType\n"
120 "-m op limit initial pattern to given op\n"
122 "-n skip initial pattern\n"
123 "-N skip initial ttdt_open(), also\n"
125 "command [args] invoke command [with args] and snoop its TT API calls\n"
126 "-e script Take script as a tttrace setting. See tttracefile(4).\n"
128 "options ::= [-Tu] [-S sessid] [-w n] [-l n] [-o snoopfile] [-O tracefile]\n"
129 "-T trace (even initial) TT API calls made by ttsnoop\n"
130 "-u map (de-iconify) on snoop output\n"
131 "-S sessid set default session to sessid\n"
132 "-X set default session to tt_X_session of $DISPLAY\n"
133 "-w n set global timeout to n seconds [default: 20]\n"
134 "-l n set tttrace dtterm saveLines to n lines [default: 5000]\n"
135 "-o snoopfile log snoop output to snoopfile\n"
136 "-O tracefile log api tracing to tracefile\n"
138 "-xrm \"*DtTerm.saveLines: n\"\n"
139 "-xrm \"*DtTerm.rows: n\"\n"
140 "-xrm \"*DtTerm.columns: n\"\n"
141 "-xrm \"*DtTerm.mapOnOutput: true\"\n";
146 if (unlinkSnoopFile) {
147 if (unlink( snoopFile ) == -1) {
148 clog << "ttsnoop: unlink( \"" << snoopFile;
149 clog << "\"): " << strerror( errno ) << endl;
151 unlinkSnoopFile = False;
154 if (unlinkTraceFile) {
155 if (unlink( traceFile ) == -1) {
156 clog << "ttsnoop: unlink( \"" << traceFile;
157 clog << "\"): " << strerror( errno ) << endl;
159 unlinkTraceFile = False;
179 child = waitpid( snoopedPid, &status, WNOHANG );
180 if ((child > 0) && WIFEXITED( status )) {
181 snoopStream << endl << endl << "SIGCHLD: WEXITSTATUS=="
182 << WEXITSTATUS(status) << ": "
183 << tttraceCmd.str() << endl << endl;
191 #if defined(SVR4) || defined(aix) || defined(hpux) || defined(__osf__)
193 typedef void (*sig_pf_t)(int);
194 #define SIG_PF sig_pf_t
204 struct sigaction act;
205 act.sa_handler = handler;
206 sigemptyset(&act.sa_mask);
208 return 0==sigaction(sig, &act, NULL);
209 #elif defined(OPT_BSD_SIGNAL)
210 return SIG_ERR!=signal(sig, handler);
212 return SIG_ERR!=sigset(sig, handler);
217 installSignalHandler()
219 _tt_sigset( SIGHUP, signalHandler );
220 _tt_sigset( SIGINT, signalHandler );
221 _tt_sigset( SIGQUIT, signalHandler );
222 _tt_sigset( SIGPIPE, signalHandler );
223 _tt_sigset( SIGTERM, signalHandler );
224 _tt_sigset( SIGCHLD, signalHandler );
225 _tt_sigset( SIGCONT, signalHandler );
231 const char *callBackType,
238 if (snoopStream.bad()) {
242 time_t now = time( 0 );
243 strftime( timeBuf, sizeof( timeBuf ), "%T", localtime( &now ));
244 snoopStream << timeBuf << " (" << callBackType << ")" << callBack;
245 snoopStream << "( " << "(Tt_message)" << (void *)msg << ", ";
247 snoopStream << "(Tt_pattern)" << (void *)pat;
249 snoopStream << "...";
251 snoopStream << " ): ";
252 char *msgString = tt_message_print( msg );
253 Tt_status status = tt_ptr_error( msgString );
254 if (status == TT_OK) {
255 snoopStream << endl << msgString << endl;
257 snoopStream << status << endl;
259 tt_free( msgString );
262 static Tt_callback_action
268 DtTtCreated( DTTT_MESSAGE, msg ); // XXX bad idea?
269 snoopIt( "Tt_callback_action", justSnoopIt, msg, pat, True );
270 return TT_CALLBACK_PROCESSED;
279 unsigned char *contents,
285 tt_free( (caddr_t)contents );
288 snoopIt( "Ttmedia_load_pat_cb", _DtTtMediaLoadPatCb, msg );
292 /*** DTB_USER_CODE_END
294 *** End of user code section
296 **************************************************************************/
301 * command line options...
303 static XrmOptionDescRec optionDescList[] = {
304 {"-session", "*session", XrmoptionSepArg, (XPointer)NULL}
306 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
307 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
311 * Application Resources
313 static XtResource resources[] = {
314 {"session", "Session", XtRString, sizeof(String),
315 XtOffsetOf(DtbAppResourceRec, session_file), XtRImmediate, (XtPointer)NULL}
317 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
318 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
321 DtbAppResourceRec dtb_app_resource_rec;
325 * main for application ttsnoop
328 main(int argc, char **argv)
330 Widget toplevel = NULL;
331 Display *display = NULL;
333 Atom save_yourself_atom;
335 Pixmap icon_pixmap = NULL;
336 Pixmap icon_mask_pixmap = NULL;
338 /**************************************************************************
339 *** DTB_USER_CODE_START
341 *** No initialization has been done.
343 *** Add local variables and code.
347 * The application must call DtTermInitialize() before
348 * initializing the Xt Toolkit with XtAppInitialize(3X).
352 /*** DTB_USER_CODE_END
354 *** End of user code section
356 **************************************************************************/
358 toplevel = XtVaAppInitialize(&app, "Ttsnoop",
359 optionDescList, XtNumber(optionDescList),
360 &argc, argv, (String *)NULL,
364 * Get display and verify initialization was successful.
366 if (toplevel != NULL)
368 display = XtDisplayOfObject(toplevel);
372 fprintf(stderr, "Could not open display.");
377 * Save the toplevel widget so it can be fetched later as needed.
379 dtb_save_toplevel_widget(toplevel);
382 * Save the command used to invoke the application.
384 dtb_save_command(argv[0]);
386 XtGetApplicationResources(toplevel, (XtPointer)&dtb_app_resource_rec,
387 resources, XtNumber(resources), (Arg *)NULL, 0);
390 /**************************************************************************
391 *** DTB_USER_CODE_START
393 *** A connection to the X server has been established, and all
394 *** initialization has been done.
396 *** Add extra initialization code after this comment.
400 PixelSet pixels[MAX_NUM_COLORS];
402 short act, inact, prim, second;
403 XmeGetPixelData( DefaultScreen( display ), &colorUse, pixels,
404 &act, &inact, &prim, &second );
405 Pixmap pixmap = XmGetPixmap( DefaultScreenOfDisplay( display ),
406 "DtTtsnp.l", pixels[1].fg, pixels[1].bg );
407 XtVaSetValues( toplevel, XmNiconPixmap, pixmap, NULL) ;
408 pixmap = XmeGetMask( XtScreen( toplevel ), "DtTtsnp.l" );
409 XtVaSetValues( toplevel, XmNiconMask, pixmap, NULL) ;
411 Boolean committed2Snooping = False;
413 while ((c = getopt(argc, argv, "?F:<:v:nNe:TuS:Xw:l:o:O:")) != -1) {
416 if (! optImmediateSnooping) {
417 clog << Usage; exit( 2 );
419 committed2Snooping = 1;
420 listAppend( scopeFiles, scopeFilesCount, char *, optarg );
423 if (! optImmediateSnooping) {
424 clog << Usage; exit( 2 );
426 committed2Snooping = 1;
427 listAppend( senders, sendersCount, char *, optarg );
430 if ((! optImmediateSnooping) || (vtype != 0)) {
431 clog << Usage; exit( 2 );
433 committed2Snooping = 1;
437 if (! optImmediateSnooping) {
438 clog << Usage; exit( 2 );
440 committed2Snooping = 1;
441 listAppend( ops, opsCount, char *, optarg );
444 if (committed2Snooping) {
445 clog << Usage; exit( 2 );
447 optImmediateSnooping = False;
450 if (committed2Snooping) {
451 clog << Usage; exit( 2 );
453 optImmediateSnooping = False;
454 optImmediateTtOpen = False;
457 optTraceScript = optarg;
460 optImmediateTracing = True;
463 optMapOnOutput = True;
466 if (optImmediateSession != 0) {
467 clog << Usage; exit( 2 );
469 optImmediateSession = optarg;
472 if (optImmediateSession != 0) {
473 clog << Usage; exit( 2 );
475 optImmediateXSession = True;
478 globalTimeout = atoi( optarg );
479 if (globalTimeout > 0) {
480 globalTimeout *= 1000;
484 globalSaveLines = atoi( optarg );
487 if (snoopFile != 0) {
488 clog << Usage; exit( 2 );
491 unlinkSnoopFile = False;
494 if (traceFile != 0) {
495 clog << Usage; exit( 2 );
498 unlinkTraceFile = False;
502 clog << Usage; exit( 2 );
506 installSignalHandler();
507 if (traceFile == 0) {
509 // Set up fifo for trace output
511 traceFile = tempnam( 0, "ttsnt" );
512 if (mkfifo( traceFile, S_IWUSR | S_IRUSR ) == -1) {
513 clog << "ttsnoop: mkfifo( \"" << traceFile << "\" ) = ";
514 clog << strerror( errno ) << endl;
517 apiTracerArgv[ 0 ] = "tail";
518 apiTracerArgv[ 1 ] = "+0f";
519 apiTracerArgv[ 2 ] = traceFile;
520 if (snoopFile == 0) {
522 // Set up fifo for snoop output
524 snoopFile = tempnam( 0, "ttsnp" );
525 if (mkfifo( snoopFile, S_IWUSR | S_IRUSR ) == -1) {
526 clog << "ttsnoop: mkfifo( \"" << snoopFile << "\" ) = ";
527 clog << strerror( errno ) << endl;
530 snooperArgv[ 0 ] = "tail";
531 snooperArgv[ 1 ] = "+0f";
532 snooperArgv[ 2 ] = snoopFile;
535 if (committed2Snooping) {
536 clog << Usage; exit( 2 );
538 optImmediateSnooping = False;
539 optImmediateTtOpen = False;
540 listAppend( snoopedArgs, snoopedArgsCount, char *, "tttrace" );
541 listAppend( snoopedArgs, snoopedArgsCount, char *, "-o" );
542 listAppend( snoopedArgs, snoopedArgsCount, char *, snoopFile );
543 tttraceCmd << "tttrace -o " << snoopFile;
544 if (optTraceScript != 0) {
545 listAppend( snoopedArgs, snoopedArgsCount, char *, "-e" );
546 listAppend( snoopedArgs, snoopedArgsCount, char *,
548 tttraceCmd << " -e \"" << optTraceScript << "\"";
550 for (int i = optind; i < argc; i++) {
551 listAppend( snoopedArgs, snoopedArgsCount, char *,
553 tttraceCmd << " " << argv[i];
556 listAppend( snoopedArgs, snoopedArgsCount, char *, 0 );
560 #define AIX_STRING_LIST (char * const *)
562 #define AIX_STRING_LIST
565 if (snoopedArgsCount > 0) {
567 switch (snoopedPid) {
569 clog << "ttsnoop: fork(): " << strerror( errno ) << endl;
572 execvp( snoopedArgs[0], AIX_STRING_LIST snoopedArgs );
573 clog << "ttsnoop: execvp(): " << strerror( errno ) << endl;
576 installSignalHandler();
579 /*** DTB_USER_CODE_END
581 *** End of user code section
583 **************************************************************************/
588 * Initialize all global variables.
590 dtbTtsnoopTtsnoopWinInfo_clear(&dtb_ttsnoop_ttsnoop_win);
591 dtbApiTracerTracerInfo_clear(&dtb_api_tracer_tracer);
592 dtbTtChooserChooserInfo_clear(&dtb_tt_chooser_chooser);
593 dtbPatternPropsPatternPropsInfo_clear(&dtb_pattern_props_pattern_props);
594 dtbStringChooserStringChooserInfo_clear(&dtb_string_chooser_string_chooser);
595 dtbMessagePropsMessagePropsInfo_clear(&dtb_message_props_message_props);
596 dtbSessionChooserSessionChooserInfo_clear(&dtb_session_chooser_session_chooser);
597 dtbFileChooserFchooserInfo_clear(&dtb_file_chooser_fchooser);
598 dtbArgChooserArgChooserInfo_clear(&dtb_arg_chooser_arg_chooser);
599 dtbCallbackChooserCallbackChooserInfo_clear(&dtb_callback_chooser_callback_chooser);
602 * Set up the application's root window.
604 dtb_ttsnoop_ttsnoop_win.ttsnoopWin = toplevel;
605 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
606 "DtTtsnp.l", &icon_pixmap);
607 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
608 "DtTtsnp.l_m", &icon_mask_pixmap);
609 XtVaSetValues(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
610 XmNallowShellResize, True,
612 XmNiconMask, icon_mask_pixmap,
613 XmNiconPixmap, icon_pixmap,
614 XmNbackground, dtb_cvt_string_to_pixel(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "white"),
617 dtb_ttsnoop_ttsnoop_win_initialize(&(dtb_ttsnoop_ttsnoop_win), dtb_get_toplevel_widget());
620 * Map any initially-visible windows
623 save_yourself_atom = XmInternAtom(XtDisplay(toplevel),
624 "WM_SAVE_YOURSELF", False);
626 dtb_set_client_session_saveCB((DtbClientSessionSaveCB)NULL);
628 XmAddWMProtocolCallback(toplevel, save_yourself_atom,
629 dtb_session_save, (XtPointer)NULL);
632 /**************************************************************************
633 *** DTB_USER_CODE_START
635 *** All initially-mapped widgets have been created, but not
636 *** realized. Set resources on widgets, or perform other operations
637 *** that must be completed before the toplevel widget is
641 /*** DTB_USER_CODE_END
643 *** End of user code section
645 **************************************************************************/
648 XtRealizeWidget(toplevel);
651 /**************************************************************************
652 *** DTB_USER_CODE_START
654 *** The initially-mapped widgets have all been realized, and
655 *** the Xt main loop is about to be entered.
658 installSignalHandler();
659 if (snoopedArgsCount > 0) {
660 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
664 snoopStream.open( snoopFile, ios::app );
666 envStr << "TT_TRACE_SCRIPT=> ";
667 envStr << traceFile << ends;
668 traceScript = envStr.str();
669 if (optImmediateTracing) {
670 turnOnTracing( 0, 0, 0 );
672 if (optImmediateXSession) {
673 char *display = getenv( "DISPLAY" );
674 optImmediateSession = tt_X_session( display );
675 status = tt_ptr_error( optImmediateSession );
676 if (tt_is_err( status )) {
677 clog << "ttsnoop: tt_X_session( ";
681 clog << "\"" << display << "\"";
683 clog << " ) = " << (void *)optImmediateSession;
684 clog << " (" << status << ")" << endl;
688 if (optImmediateSession != 0) {
689 status = tt_default_session_set( optImmediateSession );
690 if (tt_is_err( status )) {
691 clog << "ttsnoop: tt_default_session_set( \"";
692 clog << optImmediateSession << "\" ) = ";
693 clog << status << endl;
697 if (optImmediateTtOpen) {
699 char *procid = ttdt_open( &fd, "Ttsnoop", "CDE",
700 globalVersionString, 1 );
701 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
702 "ttdt_open()", procid );
703 status = tt_ptr_error( procid );
704 if (tt_is_err( status )) {
705 char *statmsg = tt_status_message(status);
706 clog << "ttsnoop: ttdt_open() = ";
707 clog << status << ": " << statmsg << endl;
710 XtInputId id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask,
711 tttk_Xt_input_handler, procid );
712 DtTtCreated( DTTT_PROCID, procid, (void *)id );
713 if (optImmediateSnooping) {
714 Tt_pattern pat = tt_pattern_create();
715 tt_pattern_category_set( pat, TT_OBSERVE );
716 if (scopeFilesCount > 0) {
717 tt_pattern_scope_add( pat, TT_BOTH );
718 for (int i = 0; i < scopeFilesCount; i++) {
719 tt_pattern_file_add( pat, scopeFiles[i] );
722 tt_pattern_scope_add( pat, TT_SESSION );
724 char *sess = tt_default_session();
725 tt_pattern_session_add( pat, sess );
727 for (int i = 0; i < opsCount; i++) {
728 tt_pattern_op_add( pat, ops[i] );
730 for (i = 0; i < sendersCount; i++) {
731 tt_pattern_sender_add( pat, senders[i] );
734 tt_pattern_arg_add( pat, TT_MODE_UNDEFINED,
737 tt_pattern_callback_add( pat, justSnoopIt );
738 status = tt_pattern_register( pat );
739 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
740 "tt_pattern_register()", pat );
741 if (tt_is_err( status )) {
742 char *statmsg = tt_status_message(status);
743 clog << "ttsnoop: tt_pattern_register() = ";
744 clog << status << ": " << statmsg << endl;
747 DtTtCreated( DTTT_PATTERN, pat );
749 snoopPatIsRegistered = True;
753 XtSetSensitive( dtb_ttsnoop_ttsnoop_win.
754 menubar_Snoop_item_Snoop_menu_items.Off_item, False );
756 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.
757 menubar_Snoop_item_Snoop_menu_items.Off_item,
758 snoopPatIsRegistered ? "Off" : "On" );
759 if (optMapOnOutput) {
760 XtVaSetValues( dtb_ttsnoop_ttsnoop_win.ttsnoopPane,
761 DtNmapOnOutput, optMapOnOutput, 0 );
763 installSignalHandler();
765 /*** DTB_USER_CODE_END
767 *** End of user code section
769 **************************************************************************/
781 /**************************************************************************
782 *** DTB_USER_CODE_START
784 *** All automatically-generated data and functions have been defined.
786 *** Add new functions here, or at the top of the file.
789 /*** DTB_USER_CODE_END
791 *** End of user code section
793 **************************************************************************/