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 #if defined(linux) || defined(CSRG_BASED) || defined(sun)
72 #include <strstream.h>
82 //#include <Xm/ColorObj.h>
83 //#include <Xm/ColorObjP.h>
84 //extern "C" { Pixmap XmeGetMask( Screen *, const char * ); }
86 Boolean optImmediateTracing = False;
87 Boolean optMapOnOutput = False;
88 Boolean optImmediateSnooping = True;
89 Boolean optImmediateTtOpen = True;
90 Boolean optImmediateXSession = False;
91 char * optImmediateSession = 0;
92 Tt_pattern snoopPat = 0;
93 Boolean snoopPatIsRegistered = False;
95 Boolean unlinkSnoopFile = True;
97 Boolean unlinkTraceFile = True;
98 char * traceScript = 0;
99 int globalTimeout = 20000;
100 unsigned int globalSaveLines = 5000;
101 const char * globalVersionString = "1.0";
102 char ** scopeFiles = 0;
103 unsigned int scopeFilesCount = 0;
105 unsigned int opsCount = 0;
107 unsigned int sendersCount = 0;
109 pid_t snoopedPid = -1;
110 char ** snoopedArgs = 0;
111 unsigned int snoopedArgsCount = 0;
112 char * optTraceScript = 0;
113 String apiTracerArgv[ 10 ];
114 String snooperArgv[ 10 ];
115 std::ostrstream tttraceCmd;
116 std::ofstream snoopStream;
118 // Xt squats on -tf ?! XXX
120 "ttsnoop - ToolTalk graphical user interface\n"
121 "Usage: ttsnoop [options] [-F scopefile] [-< procid] [-v media] [-m op]\n"
122 " ttsnoop [options] -n|-N\n"
123 " ttsnoop [options] [-e script] command [args]\n"
125 "-F scopefile scope initial pattern also to scopefile\n"
126 "-\\< \"procid\" limit initial pattern to messages from procid\n"
127 "-v mediaType limit initial pattern to messages for mediaType\n"
128 "-m op limit initial pattern to given op\n"
130 "-n skip initial pattern\n"
131 "-N skip initial ttdt_open(), also\n"
133 "command [args] invoke command [with args] and snoop its TT API calls\n"
134 "-e script Take script as a tttrace setting. See tttracefile(4).\n"
136 "options ::= [-Tu] [-S sessid] [-w n] [-l n] [-o snoopfile] [-O tracefile]\n"
137 "-T trace (even initial) TT API calls made by ttsnoop\n"
138 "-u map (de-iconify) on snoop output\n"
139 "-S sessid set default session to sessid\n"
140 "-X set default session to tt_X_session of $DISPLAY\n"
141 "-w n set global timeout to n seconds [default: 20]\n"
142 "-l n set tttrace dtterm saveLines to n lines [default: 5000]\n"
143 "-o snoopfile log snoop output to snoopfile\n"
144 "-O tracefile log api tracing to tracefile\n"
146 "-xrm \"*DtTerm.saveLines: n\"\n"
147 "-xrm \"*DtTerm.rows: n\"\n"
148 "-xrm \"*DtTerm.columns: n\"\n"
149 "-xrm \"*DtTerm.mapOnOutput: true\"\n";
154 if (unlinkSnoopFile) {
155 if (unlink( snoopFile ) == -1) {
156 clog << "ttsnoop: unlink( \"" << snoopFile;
157 clog << "\"): " << strerror( errno ) << endl;
159 unlinkSnoopFile = False;
162 if (unlinkTraceFile) {
163 if (unlink( traceFile ) == -1) {
164 clog << "ttsnoop: unlink( \"" << traceFile;
165 clog << "\"): " << strerror( errno ) << endl;
167 unlinkTraceFile = False;
187 child = waitpid( snoopedPid, &status, WNOHANG );
188 if ((child > 0) && WIFEXITED( status )) {
189 snoopStream << endl << endl << "SIGCHLD: WEXITSTATUS=="
190 << WEXITSTATUS(status) << ": "
191 << tttraceCmd.str() << endl << endl;
199 #if defined(SVR4) || defined(aix) || defined(hpux) || defined(linux) || defined(CSRG_BASED)
201 typedef void (*sig_pf_t)(int);
202 #define SIG_PF sig_pf_t
211 #if defined(hpux) || defined(linux) || defined(CSRG_BASED)
212 struct sigaction act;
213 act.sa_handler = handler;
214 sigemptyset(&act.sa_mask);
216 return 0==sigaction(sig, &act, NULL);
217 #elif defined(OPT_BSD_SIGNAL)
218 return SIG_ERR!=signal(sig, handler);
220 return SIG_ERR!=sigset(sig, handler);
225 installSignalHandler()
227 _tt_sigset( SIGHUP, signalHandler );
228 _tt_sigset( SIGINT, signalHandler );
229 _tt_sigset( SIGQUIT, signalHandler );
230 _tt_sigset( SIGPIPE, signalHandler );
231 _tt_sigset( SIGTERM, signalHandler );
232 _tt_sigset( SIGCHLD, signalHandler );
233 _tt_sigset( SIGCONT, signalHandler );
239 const char *callBackType,
246 if (snoopStream.bad()) {
250 time_t now = time( 0 );
251 strftime( timeBuf, sizeof( timeBuf ), "%T", localtime( &now ));
252 snoopStream << timeBuf << " (" << callBackType << ")" << callBack;
253 snoopStream << "( " << "(Tt_message)" << (void *)msg << ", ";
255 snoopStream << "(Tt_pattern)" << (void *)pat;
257 snoopStream << "...";
259 snoopStream << " ): ";
260 char *msgString = tt_message_print( msg );
261 Tt_status status = tt_ptr_error( msgString );
262 if (status == TT_OK) {
263 snoopStream << endl << msgString << endl;
265 snoopStream << status << endl;
267 tt_free( msgString );
270 static Tt_callback_action
276 DtTtCreated( DTTT_MESSAGE, msg ); // XXX bad idea?
277 snoopIt( "Tt_callback_action", (void *) justSnoopIt, msg, pat, True );
278 return TT_CALLBACK_PROCESSED;
287 unsigned char *contents,
293 tt_free( (caddr_t)contents );
296 snoopIt( "Ttmedia_load_pat_cb", (void *) _DtTtMediaLoadPatCb, msg );
300 /*** DTB_USER_CODE_END
302 *** End of user code section
304 **************************************************************************/
309 * command line options...
311 static XrmOptionDescRec optionDescList[] = {
312 {"-session", "*session", XrmoptionSepArg, (XPointer)NULL}
314 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
315 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
319 * Application Resources
321 static XtResource resources[] = {
322 {"session", "Session", XtRString, sizeof(String),
323 XtOffsetOf(DtbAppResourceRec, session_file), XtRImmediate, (XtPointer)NULL}
325 /*** DTB_USER_CODE_START vvv Add structure fields below vvv ***/
326 /*** DTB_USER_CODE_END ^^^ Add structure fields above ^^^ ***/
329 DtbAppResourceRec dtb_app_resource_rec;
333 * main for application ttsnoop
336 main(int argc, char **argv)
338 Widget toplevel = NULL;
339 Display *display = NULL;
341 Atom save_yourself_atom;
343 Pixmap icon_pixmap = 0;
344 Pixmap icon_mask_pixmap = 0;
346 /**************************************************************************
347 *** DTB_USER_CODE_START
349 *** No initialization has been done.
351 *** Add local variables and code.
355 * The application must call DtTermInitialize() before
356 * initializing the Xt Toolkit with XtAppInitialize(3X).
360 /*** DTB_USER_CODE_END
362 *** End of user code section
364 **************************************************************************/
366 toplevel = XtVaAppInitialize(&app, "Ttsnoop",
367 optionDescList, XtNumber(optionDescList),
368 &argc, argv, (String *)NULL,
372 * Get display and verify initialization was successful.
374 if (toplevel != NULL)
376 display = XtDisplayOfObject(toplevel);
380 fprintf(stderr, "Could not open display.");
385 * Save the toplevel widget so it can be fetched later as needed.
387 dtb_save_toplevel_widget(toplevel);
390 * Save the command used to invoke the application.
392 dtb_save_command(argv[0]);
394 XtGetApplicationResources(toplevel, (XtPointer)&dtb_app_resource_rec,
395 resources, XtNumber(resources), (Arg *)NULL, 0);
398 /**************************************************************************
399 *** DTB_USER_CODE_START
401 *** A connection to the X server has been established, and all
402 *** initialization has been done.
404 *** Add extra initialization code after this comment.
408 PixelSet pixels[MAX_NUM_COLORS];
410 short act, inact, prim, second;
411 XmeGetPixelData( DefaultScreen( display ), &colorUse, pixels,
412 &act, &inact, &prim, &second );
413 Pixmap pixmap = XmGetPixmap( DefaultScreenOfDisplay( display ),
414 "DtTtsnp.l", pixels[1].fg, pixels[1].bg );
415 XtVaSetValues( toplevel, XmNiconPixmap, pixmap, NULL) ;
416 pixmap = XmeGetMask( XtScreen( toplevel ), "DtTtsnp.l" );
417 XtVaSetValues( toplevel, XmNiconMask, pixmap, NULL) ;
419 Boolean committed2Snooping = False;
421 while ((c = getopt(argc, argv, "?F:<:v:nNe:TuS:Xw:l:o:O:")) != -1) {
424 if (! optImmediateSnooping) {
425 clog << Usage; exit( 2 );
427 committed2Snooping = 1;
428 listAppend( scopeFiles, scopeFilesCount, char *, optarg );
431 if (! optImmediateSnooping) {
432 clog << Usage; exit( 2 );
434 committed2Snooping = 1;
435 listAppend( senders, sendersCount, char *, optarg );
438 if ((! optImmediateSnooping) || (vtype != 0)) {
439 clog << Usage; exit( 2 );
441 committed2Snooping = 1;
445 if (! optImmediateSnooping) {
446 clog << Usage; exit( 2 );
448 committed2Snooping = 1;
449 listAppend( ops, opsCount, char *, optarg );
452 if (committed2Snooping) {
453 clog << Usage; exit( 2 );
455 optImmediateSnooping = False;
458 if (committed2Snooping) {
459 clog << Usage; exit( 2 );
461 optImmediateSnooping = False;
462 optImmediateTtOpen = False;
465 optTraceScript = optarg;
468 optImmediateTracing = True;
471 optMapOnOutput = True;
474 if (optImmediateSession != 0) {
475 clog << Usage; exit( 2 );
477 optImmediateSession = optarg;
480 if (optImmediateSession != 0) {
481 clog << Usage; exit( 2 );
483 optImmediateXSession = True;
486 globalTimeout = atoi( optarg );
487 if (globalTimeout > 0) {
488 globalTimeout *= 1000;
492 globalSaveLines = atoi( optarg );
495 if (snoopFile != 0) {
496 clog << Usage; exit( 2 );
499 unlinkSnoopFile = False;
502 if (traceFile != 0) {
503 clog << Usage; exit( 2 );
506 unlinkTraceFile = False;
510 clog << Usage; exit( 2 );
514 installSignalHandler();
515 if (traceFile == 0) {
517 // Set up fifo for trace output
519 traceFile = tempnam( 0, "ttsnt" );
520 if (mkfifo( traceFile, S_IWUSR | S_IRUSR ) == -1) {
521 clog << "ttsnoop: mkfifo( \"" << traceFile << "\" ) = ";
522 clog << strerror( errno ) << endl;
525 apiTracerArgv[ 0 ] = "tail";
526 apiTracerArgv[ 1 ] = "+0f";
527 apiTracerArgv[ 2 ] = traceFile;
528 if (snoopFile == 0) {
530 // Set up fifo for snoop output
532 snoopFile = tempnam( 0, "ttsnp" );
533 if (mkfifo( snoopFile, S_IWUSR | S_IRUSR ) == -1) {
534 clog << "ttsnoop: mkfifo( \"" << snoopFile << "\" ) = ";
535 clog << strerror( errno ) << endl;
538 snooperArgv[ 0 ] = "tail";
539 snooperArgv[ 1 ] = "+0f";
540 snooperArgv[ 2 ] = snoopFile;
543 if (committed2Snooping) {
544 clog << Usage; exit( 2 );
546 optImmediateSnooping = False;
547 optImmediateTtOpen = False;
548 listAppend( snoopedArgs, snoopedArgsCount, char *, "tttrace" );
549 listAppend( snoopedArgs, snoopedArgsCount, char *, "-o" );
550 listAppend( snoopedArgs, snoopedArgsCount, char *, snoopFile );
551 tttraceCmd << "tttrace -o " << snoopFile;
552 if (optTraceScript != 0) {
553 listAppend( snoopedArgs, snoopedArgsCount, char *, "-e" );
554 listAppend( snoopedArgs, snoopedArgsCount, char *,
556 tttraceCmd << " -e \"" << optTraceScript << "\"";
558 for (int i = optind; i < argc; i++) {
559 listAppend( snoopedArgs, snoopedArgsCount, char *,
561 tttraceCmd << " " << argv[i];
564 listAppend( snoopedArgs, snoopedArgsCount, char *, 0 );
568 #define AIX_STRING_LIST (char * const *)
570 #define AIX_STRING_LIST
573 if (snoopedArgsCount > 0) {
575 switch (snoopedPid) {
577 clog << "ttsnoop: fork(): " << strerror( errno ) << endl;
580 execvp( snoopedArgs[0], AIX_STRING_LIST snoopedArgs );
581 clog << "ttsnoop: execvp(): " << strerror( errno ) << endl;
584 installSignalHandler();
587 /*** DTB_USER_CODE_END
589 *** End of user code section
591 **************************************************************************/
596 * Initialize all global variables.
598 dtbTtsnoopTtsnoopWinInfo_clear(&dtb_ttsnoop_ttsnoop_win);
599 dtbApiTracerTracerInfo_clear(&dtb_api_tracer_tracer);
600 dtbTtChooserChooserInfo_clear(&dtb_tt_chooser_chooser);
601 dtbPatternPropsPatternPropsInfo_clear(&dtb_pattern_props_pattern_props);
602 dtbStringChooserStringChooserInfo_clear(&dtb_string_chooser_string_chooser);
603 dtbMessagePropsMessagePropsInfo_clear(&dtb_message_props_message_props);
604 dtbSessionChooserSessionChooserInfo_clear(&dtb_session_chooser_session_chooser);
605 dtbFileChooserFchooserInfo_clear(&dtb_file_chooser_fchooser);
606 dtbArgChooserArgChooserInfo_clear(&dtb_arg_chooser_arg_chooser);
607 dtbCallbackChooserCallbackChooserInfo_clear(&dtb_callback_chooser_callback_chooser);
610 * Set up the application's root window.
612 dtb_ttsnoop_ttsnoop_win.ttsnoopWin = toplevel;
613 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
614 "DtTtsnp.l", &icon_pixmap);
615 dtb_cvt_image_file_to_pixmap(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
616 "DtTtsnp.l_m", &icon_mask_pixmap);
617 XtVaSetValues(dtb_ttsnoop_ttsnoop_win.ttsnoopWin,
618 XmNallowShellResize, True,
620 XmNiconMask, icon_mask_pixmap,
621 XmNiconPixmap, icon_pixmap,
622 XmNbackground, dtb_cvt_string_to_pixel(dtb_ttsnoop_ttsnoop_win.ttsnoopWin, "white"),
625 dtb_ttsnoop_ttsnoop_win_initialize(&(dtb_ttsnoop_ttsnoop_win), dtb_get_toplevel_widget());
628 * Map any initially-visible windows
631 save_yourself_atom = XmInternAtom(XtDisplay(toplevel),
632 "WM_SAVE_YOURSELF", False);
634 dtb_set_client_session_saveCB((DtbClientSessionSaveCB)NULL);
636 XmAddWMProtocolCallback(toplevel, save_yourself_atom,
637 dtb_session_save, (XtPointer)NULL);
640 /**************************************************************************
641 *** DTB_USER_CODE_START
643 *** All initially-mapped widgets have been created, but not
644 *** realized. Set resources on widgets, or perform other operations
645 *** that must be completed before the toplevel widget is
649 /*** DTB_USER_CODE_END
651 *** End of user code section
653 **************************************************************************/
656 XtRealizeWidget(toplevel);
659 /**************************************************************************
660 *** DTB_USER_CODE_START
662 *** The initially-mapped widgets have all been realized, and
663 *** the Xt main loop is about to be entered.
666 installSignalHandler();
667 if (snoopedArgsCount > 0) {
668 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
672 snoopStream.open( snoopFile, ios::app );
673 std::ostrstream envStr;
674 envStr << "TT_TRACE_SCRIPT=> ";
675 envStr << traceFile << ends;
676 traceScript = envStr.str();
677 if (optImmediateTracing) {
678 turnOnTracing( 0, 0, 0 );
680 if (optImmediateXSession) {
681 char *display = getenv( "DISPLAY" );
682 optImmediateSession = tt_X_session( display );
683 status = tt_ptr_error( optImmediateSession );
684 if (tt_is_err( status )) {
685 clog << "ttsnoop: tt_X_session( ";
689 clog << "\"" << display << "\"";
691 clog << " ) = " << (void *)optImmediateSession;
692 clog << " (" << status << ")" << endl;
696 if (optImmediateSession != 0) {
697 status = tt_default_session_set( optImmediateSession );
698 if (tt_is_err( status )) {
699 clog << "ttsnoop: tt_default_session_set( \"";
700 clog << optImmediateSession << "\" ) = ";
701 clog << status << endl;
705 if (optImmediateTtOpen) {
707 char *procid = ttdt_open( &fd, "Ttsnoop", "CDE",
708 globalVersionString, 1 );
709 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
710 "ttdt_open()", procid );
711 status = tt_ptr_error( procid );
712 if (tt_is_err( status )) {
713 char *statmsg = tt_status_message(status);
714 clog << "ttsnoop: ttdt_open() = ";
715 clog << status << ": " << statmsg << endl;
718 XtInputId id = XtAppAddInput( app, fd, (XtPointer)XtInputReadMask,
719 tttk_Xt_input_handler, procid );
720 DtTtCreated( DTTT_PROCID, procid, (void *)id );
721 if (optImmediateSnooping) {
722 Tt_pattern pat = tt_pattern_create();
723 tt_pattern_category_set( pat, TT_OBSERVE );
724 if (scopeFilesCount > 0) {
725 tt_pattern_scope_add( pat, TT_BOTH );
726 for (int i = 0; i < scopeFilesCount; i++) {
727 tt_pattern_file_add( pat, scopeFiles[i] );
730 tt_pattern_scope_add( pat, TT_SESSION );
732 char *sess = tt_default_session();
733 tt_pattern_session_add( pat, sess );
735 for (int i = 0; i < opsCount; i++) {
736 tt_pattern_op_add( pat, ops[i] );
738 for (int i = 0; i < sendersCount; i++) {
739 tt_pattern_sender_add( pat, senders[i] );
742 tt_pattern_arg_add( pat, TT_MODE_UNDEFINED,
745 tt_pattern_callback_add( pat, justSnoopIt );
746 status = tt_pattern_register( pat );
747 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.ttsnoopWin_label,
748 "tt_pattern_register()", pat );
749 if (tt_is_err( status )) {
750 char *statmsg = tt_status_message(status);
751 clog << "ttsnoop: tt_pattern_register() = ";
752 clog << status << ": " << statmsg << endl;
755 DtTtCreated( DTTT_PATTERN, pat );
757 snoopPatIsRegistered = True;
761 XtSetSensitive( dtb_ttsnoop_ttsnoop_win.
762 menubar_Snoop_item_Snoop_menu_items.Off_item, False );
764 DtTtSetLabel( dtb_ttsnoop_ttsnoop_win.
765 menubar_Snoop_item_Snoop_menu_items.Off_item,
766 snoopPatIsRegistered ? "Off" : "On" );
767 if (optMapOnOutput) {
768 XtVaSetValues( dtb_ttsnoop_ttsnoop_win.ttsnoopPane,
769 DtNmapOnOutput, optMapOnOutput, NULL );
771 installSignalHandler();
773 /*** DTB_USER_CODE_END
775 *** End of user code section
777 **************************************************************************/
789 /**************************************************************************
790 *** DTB_USER_CODE_START
792 *** All automatically-generated data and functions have been defined.
794 *** Add new functions here, or at the top of the file.
797 /*** DTB_USER_CODE_END
799 *** End of user code section
801 **************************************************************************/