void TTFile::TT_Exception ( char * str ) { #ifdef IOSTREAMSWORKS cerr << tt_status_message(tt_pointer_error(str)) << endl; #else fprintf(stderr, "%s\n", tt_status_message(tt_pointer_error(str))); #endif }
/****************************************************************************** * * Initiallize Tooltalk world. * *****************************************************************************/ static void ToolTalkError(char *errfmt, Tt_status status) { char *statmsg; if (! tt_is_err(status)) return; statmsg = tt_status_message(status); DtMsgLogMessage( "Dtexec", DtMsgLogStderr, errfmt, statmsg ); }
void _ttDtPrintStatus( const char *whence, const char *expr, Tt_status status ) { _tt_syslog( 0, LOG_ERR, "%s: %s: %s\n", whence, expr, tt_status_message( status )); }
/* * remover::close_tt() */ Tt_status remover:: close_tt() { if (! _tt_opened) { return TT_OK; } Tt_status err = tt_close(); if (err > TT_WRN_LAST) { fprintf( stderr, "%s: tt_close(): %s\n", (char *)_process_name, tt_status_message(err) ); } return err; }
/* * remover::open_tt() */ Tt_status remover:: open_tt() { char *process_id = tt_open(); Tt_status err = tt_ptr_error( process_id ); if (err == TT_OK) { _process_id = process_id; _tt_opened = TRUE; } else if (err > TT_WRN_LAST) { fprintf( stderr, "%s: tt_open(): %s\n", (char *)_process_name, tt_status_message(err) ); } return err; }
/* * rcopier::close_tt() */ Tt_status rcopier:: close_tt() { if (! _tt_opened) { return TT_OK; } Tt_status err = tt_close(); if (err > TT_WRN_LAST) { fprintf( stderr, "%s: Could not close ToolTalk because %s\n", (char *)_process_name, #ifndef TT_STATUS_MSG_TO_DO _tt_enumname( (Tt_status)err ) #else tt_status_message( err ) #endif ); } return err; }
/* * rcopier::open_tt() */ Tt_status rcopier:: open_tt() { char *process_id = tt_open(); Tt_status err = tt_ptr_error( process_id ); if (err == TT_OK) { _process_id = process_id; _tt_opened = TRUE; } else if (err > TT_WRN_LAST) { fprintf( stderr, "%s: Could not initialize ToolTalk because %s\n", (char *)_process_name, #ifndef TT_STATUS_MSG_TO_DO _tt_enumname( (Tt_status)err ) #else tt_status_message( err ) #endif ); } return err; }
/************************************************* * * Routine to catch identification reply. */ Tt_callback_action IdSelfToCallerReplyCB( Tt_message msg, Tt_pattern pattern) { Tt_state state; Tt_status status; char *errorMsg; status = tt_message_status(msg); state = tt_message_state(msg); if (state == TT_FAILED) { /* * tjg: At some point, may want to dump the following error * message into a log file. May have to wrap long messages. */ if (status < TT_ERR_LAST) errorMsg = tt_status_message(status); else errorMsg = tt_message_status_string(msg); dtexec_tttk_message_destroy(msg); DetachFromTooltalk(NULL); } else if (state == TT_HANDLED) { dtexec_tttk_message_destroy(msg); /* * Nothing substantial to do with the request-reply in the current * implementation. */ } else { } return( (Tt_callback_action) TT_CALLBACK_PROCESSED ); }
int _DtCmdCommandInvokerExecute ( char *errorMessage, /* MODIFIED */ DtSvcMsgContext replyContext, /* OBSOLETE -- always NULL */ int winMask, char *contextHost, char *contextDir, char *contextFile, /* OBSOLETE -- always NULL */ char *execParms, char *execHost, char *execString, char *procId, char *tmpFiles, DtCmdInvExecuteProc success_proc, void *success_data, DtCmdInvExecuteProc failure_proc, void *failure_data) { int ioMode, i, index1; int windowType; pid_t commandPid; char context[MAXPATHLEN]; char tmpDir [MAXPATHLEN]; char **commandArray; SPC_Channel_Ptr cmdChannel; char *theCommand = NULL; Boolean terminalRequest = False; char *commandArray2[MAX_EXEC_ARGS]; Boolean localExecution = True; Boolean xhostError; static unsigned long requestNum = 0; char *toolRequest = NULL; /* backward compatibility kludge */ myassert( !(contextFile && replyContext) ); /* * Check for a valid window-type. * This check is probably redundant but it converts the mask bits into * small integer values used by the rest of the command invoker code. */ if ((windowType= DtCmdGetWindowType(winMask))== -1) { (void) sprintf (errorMessage, errorRequest, toolRequest, DtTERMINAL, DtPERM_TERMINAL, DtOUTPUT_ONLY, DtSHARED_OUTPUT, "" /* Obsolete shell window */, DtNO_STDIO); return (_CMD_EXECUTE_FATAL); } /* * Create the command to be exec'ed. */ if (windowType == PERM_TERMINAL || windowType == TERMINAL) { _DtCmdCreateTerminalCommand (&theCommand, windowType, execString, execParms, execHost, procId, tmpFiles); terminalRequest = True; } else { /* * NO-STDIO || START-SESSION request. */ theCommand = XtMalloc( + strlen (cmd_Resources.dtexecPath) + strlen(" -open ") + 4 /* waitTime len */ + strlen(" -ttprocid ") + strlen(_DtActNULL_GUARD(procId)) + strlen(_DtActNULL_GUARD(tmpFiles)) + strlen (execString) + 5 /* for 2 quotes,2 blanks,null */); sprintf(theCommand,"%s -open %d -ttprocid '%s' %s %s", cmd_Resources.dtexecPath, 0 /* wait time zero for NO_STDIO */, _DtActNULL_GUARD(procId), _DtActNULL_GUARD(tmpFiles), execString); } /* * See if the request requires Remote Execution. */ localExecution = _DtIsSameHost(execHost,NULL); /* * If this is a terminalRequest and the Command Invoker subprocess * is not executable, return now. */ if (localExecution && terminalRequest && !cmd_Globals.subprocess_ok) { if (!(_DtCmdCheckForExecutable (cmd_Resources.dtexecPath))) { (void) sprintf (errorMessage, cmd_Globals.error_subprocess, cmd_Resources.dtexecPath); XtFree ((char *) theCommand); return (_CMD_EXECUTE_FAILURE); } else cmd_Globals.subprocess_ok = True; } /* * If this is a terminalRequest and the terminal emulator * is not executable, return now. */ if (localExecution && terminalRequest && !cmd_Globals.terminal_ok) { if (!(_DtCmdCheckForExecutable (cmd_Resources.localTerminal))) { (void) sprintf (errorMessage, cmd_Globals.error_terminal, cmd_Resources.localTerminal); XtFree ((char *) theCommand); return (_CMD_EXECUTE_FAILURE); } else cmd_Globals.terminal_ok = True; } /* * Break the command into something execvp or SPCSpawn can handle * and then free "theCommand" if this is a termianl-based request. */ commandArray = (char **) XtMalloc (MAX_EXEC_ARGS * sizeof (char *)); _DtCmdStringToArrayOfStrings (theCommand, commandArray); XtFree (theCommand); if (!localExecution) { char *netfile; char *argv[4]; char *tmp; /* REMOTE Execution */ ioMode = SPCIO_NOIO | SPCIO_SYNC_TERMINATOR | SPCIO_FORCE_CONTEXT; if ((cmdChannel = (_DtSPCOpen(execHost, ioMode, errorMessage))) == SPC_ERROR) { Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* Old syntax should no longer appear in contextHost/Dir */ myassert( (contextHost?*contextHost != '*':1) && (contextDir?*contextDir != '*':1) ); /* * Create a "netfile" for the cwd to be used. */ netfile = (char *) tt_host_file_netfile ( ((contextHost == NULL) ? execHost : contextHost), ((contextDir == NULL) ? (char *) getenv ("HOME") : contextDir)); if (tt_pointer_error (netfile) != TT_OK) { (void) sprintf (errorMessage, cmd_Globals.error_directory_name_map, ((contextDir == NULL) ? (char *) getenv ("HOME") : contextDir), ((contextHost == NULL) ? execHost : contextHost), tt_status_message (tt_pointer_error(netfile))); Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } (void) strcpy (context, netfile); tt_free (netfile); /* * First check to see if the "dtexecPath" is executable on * the remote execution host by executing it with no * options which will cause it to immediately die. * * There is no need to set up termination handler for this * because we don't care when it dies, we only care about * whether or not it can be executed. */ argv[0] = cmd_Resources.dtexecPath; argv[1] = (char *) NULL; if ((_DtSPCSpawn(argv[0], context, argv, NULL, cmdChannel, execHost, contextHost, contextDir, errorMessage)) == SPC_ERROR) { if (DtSPCErrorNumber != SPC_cannot_Chdir && DtSPCErrorNumber != SPC_Cannot_Fork && DtSPCErrorNumber != SPC_Env_Too_Big && DtSPCErrorNumber != SPC_Arg_Too_Long) /* * The Error message must mention that the dtexec * process is not executable so must overwrite the * error message returned by the Spawn function with * an appropriate message. */ (void) sprintf (errorMessage, errorRemoteSubprocess, execHost, cmd_Resources.dtexecPath); DtSPCClose(cmdChannel); Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* The dtexec process is now known to exist on the remote host */ /* * Now run a test to see if the command is executable * on this exec host. */ _DtCmdStringToArrayOfStrings (execString, commandArray2); tmp = (char *) XtMalloc (strlen (commandArray2[0]) + strlen ("whence ") + 2); (void) sprintf (tmp, "whence %s", commandArray2[0]); _DtCmdFreeStringVector (commandArray2); argv[0] = "ksh"; argv[1] = "-c"; argv[2] = tmp; argv[3] = (char *) NULL; /* * Reopen the channel */ if ((cmdChannel = (_DtSPCOpen(execHost, ioMode, errorMessage))) == SPC_ERROR) { Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_FAILURE); } /* * Set up a callback to be invoked when the test command * terminates. */ _DtSvcProcessLock(); if ((DtSPCRegisterTerminator(cmdChannel, (SPC_TerminateHandlerType) CheckCommandTerminator, (void *) ++requestNum)) == SPC_ERROR) { DtSPCClose(cmdChannel); Cmd_FreeAllocatedStringVector (commandArray); (void) strcpy (errorMessage, errorSpcTerminator); XtFree ((char *) tmp); _DtSvcProcessUnlock(); return (_CMD_EXECUTE_FAILURE); } if ((_DtSPCSpawn(argv[0], context, argv, NULL, cmdChannel, execHost, contextHost, contextDir, errorMessage)) == SPC_ERROR) { DtSPCClose(cmdChannel); (void) sprintf (errorMessage, errorRemoteSubprocess, execHost, argv[0]); Cmd_FreeAllocatedStringVector (commandArray); XtFree ((char *) tmp); _DtSvcProcessUnlock(); return (_CMD_EXECUTE_FAILURE); } /* * The command line checking process has been spawned. * There is nothing left to do but to queue the request * and return to the client's main loop. The command * line will be executed after the above spawned process * terminates. */ QueueRequest (cmdChannel, context, execHost, execString, commandArray, windowType, requestNum, replyContext, success_proc, success_data, failure_proc, failure_data); _DtSvcProcessUnlock(); XtFree(tmp); return (_CMD_EXECUTE_QUEUED); } else { /* LOCAL Execution */ /* * Must first check to see if the execvp will potentially fail. * * Since the terminal emulator is pre-appended onto the execution * string, don't want to check it (should have been done during * startup (in _DtInitializeCommandInvoker)) but must check the * execution string that was passed in as part of the message. */ /* Break the command into something execvp can handle */ _DtCmdStringToArrayOfStrings (execString, commandArray2); if (!_DtCmdCheckForExecutable (commandArray2[0])) { (void) sprintf (errorMessage, errorExec, commandArray2[0]); Cmd_FreeAllocatedStringVector (commandArray); _DtCmdFreeStringVector (commandArray2); return (_CMD_EXECUTE_FAILURE); } _DtCmdFreeStringVector (commandArray2); /* * Save the current directory and then "chdir" to the directory * to do the execution. If the chdir fails, return. */ (void) getcwd (tmpDir, MAXPATHLEN); if (!_DtCmdValidDir (_cmdClientHost, contextDir, contextHost)) { Cmd_FreeAllocatedStringVector (commandArray); (void) sprintf (errorMessage, errorChdir, contextDir, execHost); (void) chdir (tmpDir); return (_CMD_EXECUTE_FAILURE); } /* * Restore the original environment and remove any DT * specific environment variables that were added. */ (void) _DtEnvControl (DT_ENV_RESTORE_PRE_DT); /* Fork and then execvp the execution string */ for (index1 = 0; (index1 < 10) && ((commandPid = fork ()) < 0); index1++) { /* Out of resources ? */ if (errno != EAGAIN) break; /* If not out of resources, sleep and try again */ (void) sleep ((unsigned long) 2); } if (commandPid < 0) { Cmd_FreeAllocatedStringVector (commandArray); (void) chdir (tmpDir); (void) sprintf(errorMessage, errorFork, execHost); (void) _DtEnvControl (DT_ENV_RESTORE_POST_DT); return (_CMD_EXECUTE_FAILURE); } if (commandPid == 0) { #if defined(__hp_osf) || defined(__osf__) || defined(CSRG_BASED) setsid() ; #else (void) setpgrp (); #endif if (!terminalRequest ) { int fd; /* * Close stdout and redirect it to /dev/null. If this * is not done and the request writes to stdout, the * output will be queued in an "unlinked" file in * /tmp until the client using this code terminates. */ if ((fd = open ("/dev/null", O_RDWR)) > 0) (void) dup2 (fd, fileno (stdout)); } /* * Mark file descriptiors >=3 as "Close on Exec". */ { long open_max; open_max = sysconf(_SC_OPEN_MAX); if (open_max == -1) { #ifdef _SUN_OS open_max = NOFILE; #else #if defined(USL) || defined(__uxp__) || defined(_AIX) open_max = FOPEN_MAX; #else open_max = FD_SETSIZE; #endif #endif /* _SUN_OS */ } for (i=3; i < open_max; i++) (void) fcntl (i, F_SETFD, 1); } (void) execvp (commandArray[0], commandArray); /* Should never get here, but if you do, must exit */ /* * The following message will be written to the errorlog * file if the request is not a terminal requests or * to the terminal window if the request requires a * terminal. */ (void) sprintf (errorMessage, errorExec, commandArray[0]); (void) printf ("%s\n", errorMessage); (void) _exit (1); } /* * Restore the pre-fork environment. */ (void) chdir (tmpDir); (void) _DtEnvControl (DT_ENV_RESTORE_POST_DT); } Cmd_FreeAllocatedStringVector (commandArray); return (_CMD_EXECUTE_SUCCESS); }
DtMail::Session::Session(DtMailEnv & error, const char * app_name) : _events(16), _valid_keys(2048) { _DtMutex = MutexInit(); error.clear(); _object_signature = 0; _cur_key = 0; // Create the ToolTalk session for managing file locking, // if one doesn't exist. _tt_channel = tt_default_procid(); if (tt_pointer_error(_tt_channel) != TT_OK) { _tt_channel = ttdt_open(&_tt_fd, app_name, "SunSoft", "%I", 0); if (tt_pointer_error(_tt_channel) != TT_OK) { error.setError(DTME_TTFailure); DebugPrintf(1, "DtMail::createSession - ttdt_open returns %s\n", tt_status_message(tt_pointer_error(_tt_channel))); return; } } else { _tt_fd = tt_fd(); } // The event_fd is how we allow async behavior to occur in a // compatible way. We use a Unix domain socket as the file descriptor. // The client will watch for activity on this file descriptor, and // call our event routine when there is activity (either from XtMainLoop, // or through some other method). // pipe(_event_fd); _app_name = strdup(app_name); DtMailEnv b_error; _mail_rc = new MailRc(error, this); buildImplTable(error); if (error.isSet()) { return; } _obj_mutex = MutexInit(); // The default implementation is specified via the DEFAULT_BACKEND // variable. If this is not set in the .mailrc, then choose entry // zero. // const char * value; _mail_rc->getValue(b_error, "DEFAULT_BACKEND", &value); if (b_error.isNotSet()) { _default_impl = lookupImpl(value); if (_default_impl < 0) { _default_impl = 0; } } else { b_error.clear(); _default_impl = 0; } DtMailSigChldList = new DtVirtArray<SigChldInfo *>(8); _busy_cb = NULL; _busy_cb_data = NULL; _canAutoSave = DTM_TRUE; _object_signature = SessionSignature; return; }
/* * remover::ttrm_path() - tt_file_destroy() this path. */ Tt_status remover:: _ttrm_paths( _Tt_string_list_ptr paths ) { Tt_status worst_err = TT_OK; Tt_status err; bool_t abort = FALSE; while ((! paths->is_empty()) && (! abort)) { _Tt_string path = paths->top(); _Tt_string_list_ptr children; paths->pop(); if (! this->can_rm( path )) { continue; } if (_recurse) { _Tt_string_list_ptr children = _tt_dir_entries(path, FALSE); err = this->_ttrm_paths( children ); if (err > TT_WRN_LAST) { switch (err) { case TT_ERR_DBAVAIL: case TT_ERR_PATH: break; case TT_ERR_NOMP: case TT_ERR_DBEXIST: default: abort = TRUE; break; } } } if (! abort) { err = tt_file_destroy( (char *)path ); if (err > TT_WRN_LAST) { worst_err = err; if (! _force) { fprintf( stderr, catgets(_ttcatd, 8, 7, "%s: Could not remove " "ToolTalk objects of " "%s because %s\n"), (char *)_process_name, (char *)path, tt_status_message(err) ); } switch (err) { case TT_ERR_DBAVAIL: case TT_ERR_PATH: break; case TT_ERR_NOMP: case TT_ERR_DBEXIST: default: abort = TRUE; break; } } } } return worst_err; } /* ttrm_paths() */
/* * copier::do_ttcp() - Use tttar(1) to copy the objects of the _from_paths. * * Algorithm: * * if (_clonedir_mode) { * cd _from_path; tttar cfhL - . | (cd ../_to_path; tttar xfLp? -) * } else { * if (_to_path_is_dir) { * tttar cfhL - _from_paths | (cd _to_path ; tttar xfLp? - ) * } else { * tttar cfhL - _from_path | tttar xfLp? - -rename from to * } * } */ Tt_status copier:: do_ttcp() { _Tt_string cmd; _Tt_string_list_cursor from_path_cursor( _from_paths ); Tt_status err; if (_clonedir_mode) { #ifdef DO_TTTAR_AFTER_CP if (mkdir( (char *)_to_path, S_IRWXU ) != 0) { return TT_ERR_PATH; } #endif cmd = cmd.cat( "cd " ).cat( _from_paths->top()).cat( " ; "); } cmd = cmd.cat( "tttar cfhL -" ); while (from_path_cursor.next()) { _Tt_string from_path = *from_path_cursor; if (! this->can_cp( from_path )) { /* * Don't tttar any paths we know that cp(1) will * reject. We do this for clonedir mode, too, so * we can return if the cloning shouldn't be done. */ from_path_cursor.remove(); } else { /* * tt_file_destroy() any path that cp(1) will delete */ _Tt_string path2zap = _to_path; if (_to_path_is_dir) { /* * cp(1) will overwrite any entry in _to_path * that has the same name as a _from_path. */ _Tt_string dir, base; base = from_path.rsplit( '/', dir ); path2zap = _to_path.cat( "/" ).cat( base ); } err = tt_file_destroy( (char *)path2zap ); if (err > TT_WRN_LAST) { fprintf( stderr, catgets(_ttcatd, 8, 12, "%s: Could not remove " "ToolTalk objects of %s " "because %s\n"), (char *)_process_name, (char *)path2zap, tt_status_message(err) ); } } } if (_from_paths->count() <= 0) { return TT_OK; } if (_clonedir_mode) { /* * In clonedir mode, we just tttar up everything in * the directory we're cloning. */ cmd = cmd.cat( " ." ); } else { from_path_cursor.reset(); while (from_path_cursor.next()) { cmd = cmd.cat( " " ).cat( *from_path_cursor ); } } cmd = cmd.cat( " |" ); if (_to_path_is_dir) { cmd = cmd.cat( " ( cd " ); if (_clonedir_mode) { char realpath_buf[ MAXPATHLEN ]; /* * If we're in _clonedir_mode, then we'll be * cd'ing down into _from_path, and so we want * a realpath of _to_path to cd over to, * because if _from_path is a symlink then * in _from_path "../_to_path" is _not_ _to_path. */ char *real_to_path = _tt_get_realpath( (char *)_to_path, realpath_buf ); if (real_to_path == NULL) { fprintf( stderr, "%s: %s: %s\n", (char *)_process_name, (char *)_to_path, strerror(errno) ); return TT_ERR_PATH; } cmd = cmd.cat( real_to_path ); } else { cmd = cmd.cat( _to_path ); } cmd = cmd.cat( " ;" ); } cmd = cmd.cat( " tttar xfL" ); if (_preserve) { cmd = cmd.cat( "p" ); } cmd = cmd.cat( " -" ); /* * Use the hack we built into tttar(1) to rename paths * as they're extracted. Rename each _from_path to _to_path. */ from_path_cursor.reset(); while (from_path_cursor.next()) { _Tt_string from_path = *from_path_cursor; cmd = cmd.cat( " -rename " ).cat( from_path ) .cat( " " ).cat( _to_path ); /* * If the copy is to be made in a subdirectory of _to_path, * make tttar maps _from_path to the appropriate * subdirectory of _to_path as it extracts. */ if ((_to_path_is_dir) && (! _clonedir_mode)) { _Tt_string dir_name; cmd = cmd.cat( "/" ) .cat( from_path.rsplit( '/', dir_name )); } } if (_to_path_is_dir) { cmd = cmd.cat( " )" ); } //printf( "Invoking: %s\n", (char *)cmd ); int sys_status = system( (char *)cmd ); #ifdef DO_TTTAR_AFTER_CP if (_clonedir_mode) { /* * remove the target directory, so that cp(1) won't * see it and make _from_path a subdirectory of it. */ if (rmdir( (char *)_to_path ) != 0) { fprintf( stderr, "%s: rmdir(\"%s\"): %s\n", (char *)_process_name, (char *)_to_path, strerror(errno) ); return TT_ERR_PATH; } } #endif if (WIFEXITED(sys_status)) { if (WEXITSTATUS(sys_status) == 0) { return TT_OK; } else { return TT_ERR_INTERNAL; } } else { fprintf( stderr, "%s: system(\"%s\"): %d\n", (char *)_process_name, sys_status ); return TT_ERR_INTERNAL; } } /* do_ttcp() */