Files
cdesktop/cde/programs/ttsnoop/DtTt.C
Jon Trulson af6c2fd881 ttsnoop: drag into a modern C++ century
This program has never worked very well, and it may still not work
very well.  This commit removes the ancient C++ headers and uses
modern replacements with some changes required due to the different
interfaces.

It builds a lot cleaner, and no longer does stupid things like
deleteing char *, ostream.str()'s, and the like.

This program could be really useful if it worked well. Some thought
should be givien in the future to decouple this SW from dtappbuilder
and maybe just rewrite from scratch.
2018-06-29 13:48:06 -06:00

729 lines
16 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $XConsortium: DtTt.C /main/4 1996/03/19 10:47:59 barstow $
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sstream>
#include <Xm/TextF.h>
#include <Dt/SpinBox.h>
#include <Dt/HelpDialog.h>
#include "tt_c++.h"
#include "DtTt.h"
#include "messageProps_ui.h"
#include "patternProps_ui.h"
static const char ** dtTtProcids = 0;
static const void ** dtTtProcidClientDatums = 0;
static unsigned int dtTtProcidsCount = 0;
static Tt_pattern * dtTtPatterns = 0;
static unsigned int dtTtPatternsCount = 0;
static Tt_message * dtTtMessages = 0;
static unsigned int dtTtMessagesCount = 0;
static Tt_pattern ** dtTtDtSessions = 0;
static unsigned int dtTtDtSessionsCount = 0;
static Tt_pattern ** dtTtDtFiles = 0;
static unsigned int dtTtDtFilesCount = 0;
int _DtTtPatsNameKey = (int) (long) DtTtNth;
extern Tt_pattern snoopPat;
int
listGrow(
void ** pList,
unsigned int & listCount,
size_t elemSize
)
{
void *newList;
newList = realloc( *pList, (1 + listCount) * elemSize );
if (newList == 0) {
return 0;
}
*pList = newList;
listCount++;
return 1;
}
XmString
DtTtStatusString(
Tt_status status
)
{
char *s = tt_status_string( status );
XmString s2 = XmStringCreateLocalized( s );
tt_free( s );
return s2;
}
Tt_status
DtTtCreated(
DtTtType type,
const void * entity,
const void * clientData
)
{
Tt_status status = tt_ptr_error( entity );
if ((tt_is_err( status )) || (entity == 0)) {
return TT_OK;
}
switch (type) {
char *proc;
case DTTT_PROCID:
proc = strdup( (const char *)entity );
if (proc == 0) {
return TT_ERR_NOMEM;
}
if (! listAppend( dtTtProcids, dtTtProcidsCount, const char *,
proc ))
{
return TT_ERR_NOMEM;
}
dtTtProcidsCount--; // shared by both lists
if (! listAppend( dtTtProcidClientDatums, dtTtProcidsCount,
const void *, clientData ))
{
return TT_ERR_NOMEM;
}
break;
case DTTT_MESSAGE:
if (DtTtIndex( type, entity ) >= 0) {
return TT_OK;
}
if (! listAppend( dtTtMessages, dtTtMessagesCount, Tt_message,
(const Tt_message)entity ))
{
return TT_ERR_NOMEM;
}
break;
case DTTT_PATTERN:
if (DtTtIndex( type, entity ) >= 0) {
return TT_OK;
}
if (! listAppend( dtTtPatterns, dtTtPatternsCount, Tt_pattern,
(const Tt_pattern)entity ))
{
return TT_ERR_NOMEM;
}
break;
case DTTT_PTYPE:
case DTTT_OTYPE:
case DTTT_OBJECT:
case DTTT_SESSION:
case DTTT_DTSESSION:
case DTTT_DTFILE:
case DTTT_OP:
abort();
break;
}
return TT_OK;
}
Tt_status
DtTtCreated(
DtTtType type,
Tt_pattern * entity,
const char * name
)
{
if ((tt_is_err( tt_ptr_error( entity ) )) || (entity == 0)) {
return TT_OK;
}
if ((tt_is_err( tt_ptr_error( name ) )) || (name == 0)) {
return TT_OK;
}
switch (type) {
case DTTT_PROCID:
case DTTT_MESSAGE:
case DTTT_PATTERN:
case DTTT_PTYPE:
case DTTT_OTYPE:
case DTTT_OBJECT:
case DTTT_SESSION:
case DTTT_OP:
abort();
break;
case DTTT_DTSESSION:
tt_pattern_user_set( *entity, _DtTtPatsNameKey,
strdup( name ));
if (DtTtIndex( type, entity ) >= 0) {
return TT_OK;
}
if (! listAppend( dtTtDtSessions, dtTtDtSessionsCount,
Tt_pattern *, (Tt_pattern *)entity ))
{
return TT_ERR_NOMEM;
}
break;
case DTTT_DTFILE:
tt_pattern_user_set( *entity, _DtTtPatsNameKey,
strdup( name ));
if (DtTtIndex( type, entity ) >= 0) {
return TT_OK;
}
if (! listAppend( dtTtDtFiles, dtTtDtFilesCount,
Tt_pattern *, (Tt_pattern *)entity ))
{
return TT_ERR_NOMEM;
}
break;
}
while (*entity != 0) {
DtTtCreated( DTTT_PATTERN, *entity );
entity++;
}
return TT_OK;
}
void *
DtTtNth(
DtTtType type,
int n
)
{
switch (type) {
case DTTT_PROCID:
if ((n < 0) || (n >= dtTtProcidsCount)) {
return 0;
}
return (void *)dtTtProcids[ n ];
case DTTT_MESSAGE:
if ((n < 0) || (n >= dtTtMessagesCount)) {
return 0;
}
return dtTtMessages[ n ];
case DTTT_PATTERN:
if ((n < 0) || (n >= dtTtPatternsCount)) {
return 0;
}
return dtTtPatterns[ n ];
case DTTT_DTSESSION:
if ((n < 0) || (n >= dtTtDtSessionsCount)) {
return 0;
}
return dtTtDtSessions[ n ];
case DTTT_DTFILE:
if ((n < 0) || (n >= dtTtDtFilesCount)) {
return 0;
}
return dtTtDtFiles[ n ];
case DTTT_OP:
return tttk_op_string( (Tttk_op)(n+1) );
}
}
void *
DtTtNthClientDatum(
DtTtType type,
int n
)
{
switch (type) {
case DTTT_PROCID:
if ((n < 0) || (n >= dtTtProcidsCount)) {
return 0;
}
return (void *)dtTtProcidClientDatums[ n ];
default:
abort();
return 0;
}
}
void
DtTtNthClientDatumSet(
DtTtType type,
int n,
const void * clientData
)
{
switch (type) {
case DTTT_PROCID:
if ((n < 0) || (n >= dtTtProcidsCount)) {
return;
}
dtTtProcidClientDatums[ n ] = clientData;
return;
default:
abort();
}
}
int
DtTtIndex(
DtTtType type,
const void * entity
)
{
Tt_status status = tt_ptr_error( entity );
if ((tt_is_err( status )) || (entity == 0)) {
return -1;
}
switch (type) {
int i;
case DTTT_PROCID:
for (i = dtTtProcidsCount - 1; i >= 0; i--) {
if (strcmp( dtTtProcids[i], (char *)entity) == 0) {
return i;
}
}
return -1;
case DTTT_MESSAGE:
for (i = dtTtMessagesCount - 1; i >= 0; i--) {
if (dtTtMessages[i] == entity) {
return i;
}
}
return -1;
case DTTT_PATTERN:
for (i = dtTtPatternsCount - 1; i >= 0; i--) {
if (dtTtPatterns[i] == entity) {
return i;
}
}
return -1;
case DTTT_DTSESSION:
for (i = dtTtDtSessionsCount - 1; i >= 0; i--) {
if (dtTtDtSessions[i] == entity) {
return i;
}
}
return -1;
case DTTT_DTFILE:
for (i = dtTtDtFilesCount - 1; i >= 0; i--) {
if (dtTtDtFiles[i] == entity) {
return i;
}
}
return -1;
case DTTT_OP:
for (i = 1; i < TTDT_OP_LAST; i++) {
if (0 == strcmp( tttk_op_string( (Tttk_op)i ),
(char *)entity ))
{
return i;
}
}
return -1;
}
}
Tt_status
DtTtDestroyed(
DtTtType type,
const void * entity
)
{
Tt_status status = tt_ptr_error( entity );
if ((tt_is_err( status )) || (entity == 0)) {
return TT_OK;
}
switch (type) {
int i, j;
Tt_pattern *pats;
case DTTT_PROCID:
for (i = dtTtProcidsCount - 1; i >= 0; i--) {
if (strcmp( dtTtProcids[i], (char *)entity) == 0) {
break;
}
}
if (i < 0) {
return TT_WRN_NOTFOUND;
}
for (j = i; j < dtTtProcidsCount - 1; j++) {
dtTtProcids[j] = dtTtProcids[j+1];
}
for (j = i; j < dtTtProcidsCount - 1; j++) {
dtTtProcidClientDatums[j] =
dtTtProcidClientDatums[j+1];
}
dtTtProcidsCount--;
break;
case DTTT_MESSAGE:
for (i = dtTtMessagesCount - 1; i >= 0; i--) {
if (dtTtMessages[i] == entity) {
break;
}
}
if (i < 0) {
return TT_WRN_NOTFOUND;
}
for (j = i; j < dtTtMessagesCount - 1; j++) {
dtTtMessages[j] = dtTtMessages[j+1];
}
dtTtMessagesCount--;
break;
case DTTT_PATTERN:
if (snoopPat == entity) snoopPat = 0;
for (i = dtTtPatternsCount - 1; i >= 0; i--) {
if (dtTtPatterns[i] == entity) {
break;
}
}
if (i < 0) {
return TT_WRN_NOTFOUND;
}
for (j = i; j < dtTtPatternsCount - 1; j++) {
dtTtPatterns[j] = dtTtPatterns[j+1];
}
dtTtPatternsCount--;
break;
case DTTT_DTSESSION:
for (i = dtTtDtSessionsCount - 1; i >= 0; i--) {
if (dtTtDtSessions[i] == entity) {
break;
}
}
if (i < 0) {
return TT_WRN_NOTFOUND;
}
pats = (Tt_pattern *)entity;
while (*pats != 0) {
DtTtDestroyed( DTTT_PATTERN, *pats );
pats++;
}
for (j = i; j < dtTtDtSessionsCount - 1; j++) {
dtTtDtSessions[j] = dtTtDtSessions[j+1];
}
dtTtDtSessionsCount--;
break;
case DTTT_DTFILE:
for (i = dtTtDtFilesCount - 1; i >= 0; i--) {
if (dtTtDtFiles[i] == entity) {
break;
}
}
if (i < 0) {
return TT_WRN_NOTFOUND;
}
pats = (Tt_pattern *)entity;
while (*pats != 0) {
DtTtDestroyed( DTTT_PATTERN, *pats );
pats++;
}
for (j = i; j < dtTtDtFilesCount - 1; j++) {
dtTtDtFiles[j] = dtTtDtFiles[j+1];
}
dtTtDtFilesCount--;
break;
}
return TT_OK;
}
Tt_status
DtTtSetLabel(
Widget labelWidget,
const char *string
)
{
if (labelWidget == 0) {
return TT_OK;
}
XmString labelXmString = XmStringCreateLocalized( (String)string );
XtVaSetValues( labelWidget, XmNlabelString, labelXmString, NULL );
XmStringFree( labelXmString );
return TT_OK;
}
Tt_status
DtTtSetLabel(
Widget labelWidget,
const char *func,
void *val
)
{
Tt_status status = tt_ptr_error( val );
std::ostringstream errStream;
errStream << func << " = " << val << " (" << status << ")" << ends;
const char *label = errStream.str().c_str();
DtTtSetLabel( labelWidget, label );
return status;
}
Tt_status
DtTtSetLabel(
Widget labelWidget,
const char *func,
Tt_status status
)
{
std::ostringstream errStream;
errStream << func << " = " << status << ends;
const char *label = errStream.str().c_str();
DtTtSetLabel( labelWidget, label );
return status;
}
int
DtTtSetLabel(
Widget labelWidget,
const char *func,
int returnVal
)
{
std::ostringstream errStream;
errStream << func << " = " << returnVal << ends;
const char *label = errStream.str().c_str();
DtTtSetLabel( labelWidget, label );
return returnVal;
}
static XmString *
_DtTtChoices(
Tt_pattern ** pPats,
int count
)
{
// XXX when to free?
XmString *items = (XmString *)XtMalloc( count * sizeof( XmString ));
if (items == 0) {
return 0;
}
for (int i = 0; i < count; i++) {
std::ostringstream itemStream;
itemStream << (void *)pPats[ i ];
char *name = (char *)
tt_pattern_user( *pPats[ i ], _DtTtPatsNameKey );
if (! tt_is_err( tt_ptr_error( name ))) {
itemStream << " " << name;
tt_free( name );
}
itemStream << ends;
char *string = const_cast<char *>(itemStream.str().c_str());
items[ i ] = XmStringCreateLocalized( string );
}
return items;
}
XmString *
_DtTtChoices(
DtTtType type,
int * itemCount
)
{
*itemCount = 0;
switch (type) {
XmString *items;
int i;
int opCount;
case DTTT_PROCID:
items = (XmString *)
XtMalloc( dtTtProcidsCount * sizeof( XmString ));
if (items == 0) {
return 0;
}
*itemCount = dtTtProcidsCount;
for (i = 0; i < dtTtProcidsCount; i++) {
items[ i ] = XmStringCreateLocalized(
(String)dtTtProcids[ i ] );
}
return items;
case DTTT_MESSAGE:
items = (XmString *)
XtMalloc( dtTtMessagesCount * sizeof( XmString ));
if (items == 0) {
return 0;
}
*itemCount = dtTtMessagesCount;
for (i = 0; i < dtTtMessagesCount; i++) {
std::ostringstream itemStream;
itemStream << (void *)dtTtMessages[ i ];
char *op = tt_message_op( dtTtMessages[ i ] );
if (! tt_is_err( tt_ptr_error( op ))) {
itemStream << " " << op;
tt_free( op );
}
char *id = tt_message_id( dtTtMessages[ i ] );
if (! tt_is_err( tt_ptr_error( id ))) {
itemStream << " " << id;
tt_free( id );
}
itemStream << ends;
char *string = const_cast<char *>(itemStream.str().c_str());
items[ i ] = XmStringCreateLocalized( string );
}
return items;
case DTTT_PATTERN:
items = (XmString *)
XtMalloc( dtTtPatternsCount * sizeof( XmString ));
if (items == 0) {
return 0;
}
*itemCount = dtTtPatternsCount;
for (i = 0; i < dtTtPatternsCount; i++) {
std::ostringstream itemStream;
itemStream << (void *)dtTtPatterns[ i ] << ends;
items[ i ] = XmStringCreateLocalized(
const_cast<char *>(itemStream.str().c_str()) );
}
return items;
case DTTT_DTSESSION:
*itemCount = dtTtDtSessionsCount;
return _DtTtChoices( dtTtDtSessions, dtTtDtSessionsCount );
case DTTT_DTFILE:
*itemCount = dtTtDtFilesCount;
return _DtTtChoices( dtTtDtFiles, dtTtDtFilesCount );
case DTTT_OP:
// XXX when to free? ditto for each case
opCount = ((int)TTDT_OP_LAST) - 1;
items = (XmString *)
XtMalloc( opCount * sizeof( XmString ));
if (items == 0) {
return 0;
}
*itemCount = opCount;
for (i = 1; i <= opCount; i++) {
items[ i-1 ] = XmStringCreateLocalized(
(String)tttk_op_string( (Tttk_op)i ));
}
return items;
}
}
#if defined(aix)
#define AIX_CONST_STRING (char *)
#else
#define AIX_CONST_STRING
#endif
void
_DtOpen(
Widget label,
const char * cmd,
const char * tempnamTemplate
)
{
char *file = tempnam( 0, AIX_CONST_STRING tempnamTemplate );
std::ostringstream cmdStream;
cmdStream << cmd << " > " << file << ends;
int sysStat = system( cmdStream.str().c_str() );
if (! WIFEXITED( sysStat )) {
std::ostringstream func;
func << "system( \"" << cmdStream.str() << "\" )" << ends;
DtTtSetLabel( label, func.str().c_str(), sysStat );
return;
}
if (WEXITSTATUS( sysStat ) != 0) {
DtTtSetLabel( label, cmdStream.str().c_str(), WEXITSTATUS( sysStat ));
return;
}
_DtOpen( label, file );
}
void
_DtOpen(
Widget label,
const char * file
)
{
std::ostringstream labelStream;
labelStream << "dtaction Open " << file << ends;
DtTtSetLabel( label, labelStream.str().c_str() );
std::ostringstream cmd;
cmd << "( unset TT_TRACE_SCRIPT; if dtaction Open " << file
<< "; then :; else textedit " << file << "; fi; sleep 600; rm -f "
<< file << " ) &" << ends;
system( cmd.str().c_str() );
}
void
_DtOpen(
Widget label,
void * buf,
size_t len,
const char * tempnamTemplate
)
{
char *file = tempnam( 0, AIX_CONST_STRING tempnamTemplate );
int fd = open( file, O_WRONLY|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR );
if (write( fd, buf, len ) < 0) {
DtTtSetLabel( label, file, errno );
return;
}
close( fd );
_DtOpen( label, file );
}
void
_DtMan(
Widget label,
const char * topic
)
{
std::ostringstream labelStream;
labelStream << "dtaction Dtmanpageview " << topic << ends;
DtTtSetLabel( label, labelStream.str().c_str() );
std::ostringstream cmd;
cmd << "unset TT_TRACE_SCRIPT; if dtaction Dtmanpageview " << topic
<< "; then :; else cmdtool -c man " << topic << "; fi &" << ends;
system( cmd.str().c_str() );
}
Boolean
_DtCanHelp(
const char *topics
)
{
if (topics == 0) return False;
if (strchr( topics, ' ' ) != 0) {
// Must not be a list of man pages
return False;
}
return True;
}
Boolean
_DtHelped(
Widget helpDialog
)
{
char *topics;
XtVaGetValues( helpDialog, DtNstringData, &topics, NULL );
if (! _DtCanHelp( topics )) {
return False;
}
char *newTopics = strdup( topics );
const char *whiteSpace = "(12345689) \t:-,.*\n";
const char *topic = strtok( newTopics, whiteSpace );
while (topic != 0) {
_DtMan( 0, topic );
topic = strtok( 0, whiteSpace );
}
free( newTopics );
return True;
}