Exemplo n.º 1
0
/*----------------------------------------------------------------------+*/
SPC_Channel_Ptr SPC_Lookup_Channel(int cid,
				   SPC_Connection_Ptr connection)
/*----------------------------------------------------------------------+*/
{
  
  SPC_Channel_Ptr spc;

  if(!cid)
    return(NULL);
  
  _DtSvcProcessLock();
  for(spc=spc_activation_list; spc; spc=spc->next)
    /* This test is here because:
       a. Only remote channels have cid's
       b. It is possible for multiple remote servers to have
          the same cid (which is simply the address of the channel),
	  so we need to distinguish among remote channels, but
       c. channels on the remote daemon have cid's, but a null connection.
       */
    if((spc->cid == cid) &&
       (!spc->connection ||
	(spc->connection == connection))) {
	_DtSvcProcessUnlock();
	return(spc);
    }
  
  _DtSvcProcessUnlock();
  return(NULL);
}
Exemplo n.º 2
0
char *
Dt11GetMessage(
	char *filename,
	int set,
	int n,
	char *s)
{
        char *msg;
        static int first = 1;
        static nl_catd nlmsg_fd;
	static char *nlmsg_filename = NULL;

	_DtSvcProcessLock();
        if ( NULL == nlmsg_filename || 0 != strcmp(nlmsg_filename, filename) )
        {
		nlmsg_fd = catopen(filename, NL_CAT_LOCALE);
		if (nlmsg_filename)
		{
		    free(nlmsg_filename);
		    nlmsg_filename = NULL;
		}
		nlmsg_filename = strdup(filename);
        }
        msg=catgets(nlmsg_fd,set,n,s);
	_DtSvcProcessUnlock();
        return (msg);
}
Exemplo n.º 3
0
/*----------------------------------------------------------------------+*/
int SPC_Write_Chars(int 	fd,
		    XeString 	charptr,
		    int 	request_len)
/*----------------------------------------------------------------------+*/
{
  int numchars, numwritten;
  int numtowrite=request_len;
  
  numwritten=0;
  
  while(numwritten<request_len) {
    do
      numchars=write(fd, charptr, numtowrite);
    while(numchars == ERROR && errno == EINTR);

#ifdef DEBUG
    _DtSvcProcessLock();
    if(SPC_Print_Protocol)
      fprintf(SPC_Print_Protocol,
	      "SPC_Write_Chars -- wrote: %d of %d, expected: %d, errno: %d\n",
	      numchars, request_len, numtowrite, errno);
    _DtSvcProcessUnlock();
#endif    
       
    if(numchars == ERROR)
      return(ERROR);

    charptr    += numchars;
    numwritten += numchars;
    numtowrite -= numchars;
  }
  return(numwritten);
}
Exemplo n.º 4
0
int SUNWDtHelpdlopen()
{
    void *libDtHelpHandle = NULL;

    _DtSvcProcessLock();
    pmySUNWProcList = (SUNWHelpProcList *)malloc(sizeof(SUNWHelpProcList));
    libDtHelpHandle = dlopen("libDtHelp.so.2.1", RTLD_LAZY | RTLD_GLOBAL);
    if (libDtHelpHandle == NULL) {
	char *my_err_msg;

	my_err_msg = dlerror();
	printf("%s\n", my_err_msg);
	_DtSvcProcessUnlock();
	return(FALSE);
    }
    pmySUNWProcList->DtCreateHelpDialogSym = (SUNWWidgetProc)
			 dlsym(libDtHelpHandle, "DtCreateHelpDialog");
    pmySUNWProcList->DtCreateHelpQuickDialogSym = (SUNWWidgetProc)
			 dlsym(libDtHelpHandle, "DtCreateHelpQuickDialog");
    pmySUNWProcList->DtHelpQuickDialogGetChildSym = (SUNWWidgetProc)
			 dlsym(libDtHelpHandle, "DtHelpQuickDialogGetChild");
    pmySUNWProcList->DtHelpReturnSelectedWidgetIdSym = (SUNWIntProc)
			 dlsym(libDtHelpHandle, "DtHelpReturnSelectedWidgetId");

    _DtSvcProcessUnlock();
    return(TRUE);
}
Exemplo n.º 5
0
/*-----------------------------------------------------------------------+*/
static SbInputId SPC_RemoveInput(int 			 source,
			  SPC_Callback_Condition condition)
/*-----------------------------------------------------------------------+*/
{
  SPC_Callback_Struct *structptr = NULL;
  
  _DtSvcProcessLock();
  if (SPC_Fd_Mapping == NULL) {
    SPC_Fd_Mapping = (SPC_Callback_Struct **) 
		     XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
    memset(SPC_Fd_Mapping, 0, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
  }
  structptr=SPC_LOOKUP_FD_MAPPING(source);
  _DtSvcProcessUnlock();

  switch(condition) {
    
  case SPC_Input:
  case SPC_Terminator:
  case SPC_Client:
     return structptr->read_id;

  case SPC_Exception:
     return structptr->except_id;
    
  }

  return 0;
}
Exemplo n.º 6
0
/*----------------------------------------------------------------------+*/
void SPC_Free_Protocol_Ptr(protocol_request_ptr prot)
/*----------------------------------------------------------------------+*/
{
  _DtSvcProcessLock();
  prot->next = free_protocol_requests;
  free_protocol_requests = prot;
  _DtSvcProcessUnlock();
}
Exemplo n.º 7
0
/*----------------------------------------------------------------------+*/
void SPC_Close_Connection(SPC_Connection_Ptr connection)
/*----------------------------------------------------------------------+*/
{
  SPC_Channel_Ptr channel;
  SPC_Channel_Ptr next;
  SPC_Connection_Ptr trail, ptr;

  /* We have to be careful here.  SPC_Input_Handler may call the users
     termination handler, which in turn might close the channel, which
     may deallocate the channel.  Therefore, we grab the next channel
     from the list while we are still alive. */

  _DtSvcProcessLock();
  channel=spc_activation_list;
  connection->connected = FALSE;
  
  while(channel) {
    next=channel->next;
    if(channel->connection == connection) {
      if(!IS_SPCIO_DELAY_CLOSE(channel->IOMode))
	SPC_Channel_Terminated(channel);
      channel->connection = NULL;
    }
    channel=next;
  }
  
  SPC_XtRemoveInput(&connection->termination_id, SPC_Terminator);

  spc_close(connection->sid);
  connection->sid = (-1);

  if (connection->hostinfo)
      XeFree(connection->hostinfo);

  /* Remove the connection from the connection list */

  if(connection_list == connection)
    connection_list = connection->next;
  else {
    trail = connection_list;
    while(trail) {
      ptr = trail->next;
      if(ptr == connection) {
	trail->next = ptr->next;
	break;
      }
      trail=ptr;
    }
    if(!trail) {
      /* Here if no such connection found. */
    }
  }

  free((char *)connection);
  _DtSvcProcessUnlock();
}
Exemplo n.º 8
0
/*----------------------------------------------------------------------+*/
void SPC_Add_Connection(SPC_Connection_Ptr connection)
/*----------------------------------------------------------------------+*/
{
  
  /* Add a connection to the connection_list */
  _DtSvcProcessLock();
  connection->next = connection_list;
  connection_list = connection;
  _DtSvcProcessUnlock();
}
Exemplo n.º 9
0
/*-----------------------------------------------------------------------+*/
void SPC_XtBreak(void)
/*-----------------------------------------------------------------------+*/
{
  _DtSvcProcessLock();
  if(!spc_xe_termination_flag) {
     spc_xe_termination_flag = TRUE;
     if (SbBreakMainLoop_hookfn == NULL)
       (void) fprintf (stderr, "Error: SbBreakMainLoop = NULL\n");
     else
       (*SbBreakMainLoop_hookfn)();      
  } 
  _DtSvcProcessUnlock();
}
Exemplo n.º 10
0
/*----------------------------------------------------------------------+*/
SPC_Channel_Ptr SPC_Find_PID(int pid)
/*----------------------------------------------------------------------+*/
{
  /* Attempt to return a channel which currently handles process number PID */
  SPC_Channel_Ptr spc;

  _DtSvcProcessLock();
  for (spc = spc_activation_list; spc != NULL; spc = spc->next) {
    if (spc->pid == pid) break;
  }
  _DtSvcProcessUnlock();
  return spc;			/* NULL when not found */
}
Exemplo n.º 11
0
void
_DtInitializeCommandInvoker(
    Display *display,
    char *toolClass,	/* ignored */
    char *appClass,		/* ignored */
    DtSvcMessageProc reloadDBHandler,	/* OBSOLETE -- ignored */
    XtAppContext appContext)
{
    static	int beenCalled = 0;

    _DtSvcAppLock(appContext);

    /*
     * Prevent repeat calls
     */
    _DtSvcProcessLock();
    if ( beenCalled ) {
        _DtSvcProcessUnlock();
        return;
    }

    beenCalled++;

    cmd_Globals.app_context = appContext;

    SbAddInput_hookfn = _DtCmdSPCAddInputHandler;

    SbRemoveInput_hookfn = XtRemoveInput;

    SbAddException_hookfn = _DtCmdSPCAddExceptionHandler;

    SbRemoveException_hookfn = XtRemoveInput;

    _DtCmdBuildPathList ();

    _DtCmdInitializeErrorMessages ();

    /*
     * Must get the name of the invoking host, so that requests
     * can be checked for remote execution.
     */
    if ((DtGetShortHostname(_cmdClientHost, MAXHOSTNAMELEN)) == -1) {
        _DtCmdLogErrorMessage ("Cannot determine the local host name.\n");
    }

    _DtCmdGetResources (display);

    _DtSvcProcessUnlock();
    _DtSvcAppUnlock(appContext);
}
Exemplo n.º 12
0
Widget _DtHelpQuickDialogGetChild(
        Widget widget,
        unsigned char child )
{
    int status;

    _DtSvcProcessLock();
    status = pmySUNWProcList  || SUNWDtHelpdlopen();
    _DtSvcProcessUnlock();

    if (!status)
        return(NULL);

    return ((*pmySUNWProcList->DtHelpQuickDialogGetChildSym)(widget, child));
}
Exemplo n.º 13
0
/*----------------------------------------------------------------------+*/
SPC_Connection_Ptr SPC_Alloc_Connection(void)
/*----------------------------------------------------------------------+*/
{
  SPC_Connection_Ptr conn;

  _DtSvcProcessLock();
  conn=(SPC_Connection_Ptr) XeMalloc(sizeof(SPC_Connection));
  /* Zero the connection */
  memset(conn, 0, sizeof(SPC_Connection));
  conn->queued_remote_data = Xe_make_queue(FALSE);
  conn->termination_id = (-1);
  /* Init the socket id to "-1" because "0" is a valid file descriptor. */
  conn->sid = (-1);
  _DtSvcProcessUnlock();
  return(conn);
}
Exemplo n.º 14
0
Widget _DtCreateHelpQuickDialog(
    Widget parent,
    char *name,
    ArgList al,
    Cardinal ac)
{
    int status;

    _DtSvcProcessLock();
    status = pmySUNWProcList  || SUNWDtHelpdlopen();
    _DtSvcProcessUnlock();

    if (!status)
        return(NULL);

    return ((*pmySUNWProcList->DtCreateHelpQuickDialogSym)(parent, name, al, ac));
}
Exemplo n.º 15
0
int _DtHelpReturnSelectedWidgetId(
    Widget parent,
    Cursor cursor,
    Widget  *widget)
{
    int status;

    _DtSvcProcessLock();
    status = pmySUNWProcList  || SUNWDtHelpdlopen();
    _DtSvcProcessUnlock();

    if (!status)
        return(NULL);

    return ((*pmySUNWProcList->DtHelpReturnSelectedWidgetIdSym)(parent, cursor,
							    widget));
}
Exemplo n.º 16
0
/*----------------------------------------------------------------------+*/
void SPC_Conditional_Packet_Handler(void      * UNUSED_PARM(client_data),
				   int        * source,
				   SPCInputId * UNUSED_PARM(id))
/*----------------------------------------------------------------------+*/
{

  SPC_Channel_Ptr channel;
  
  channel = XeSPCHandleTerminator(*source);
  
  /* Okay, blast out of our wait */
  _DtSvcProcessLock();
  if( (channel==SPC_ERROR || !IS_ACTIVE(channel)) &&
      break_on_termination)
    SPC_XtBreak();
  _DtSvcProcessUnlock();
  /* return(TRUE); */
}
Exemplo n.º 17
0
/*----------------------------------------------------------------------+*/
protocol_request_ptr SPC_New_Protocol_Ptr (SPC_Channel_Ptr channel, 
					   XeChar req, 
					   int len)
/*----------------------------------------------------------------------+*/
{
  protocol_request_ptr prot;

  _DtSvcProcessLock();
  if(free_protocol_requests) {
    prot = free_protocol_requests;
    free_protocol_requests = free_protocol_requests->next;
  } else {
    prot = (protocol_request_ptr)XeMalloc(sizeof(protocol_request));
    prot->dataptr = SPC_New_Buffered_Data_Ptr();
  }
  SPC_Reset_Protocol_Ptr(prot, channel, req, len);
  _DtSvcProcessUnlock();
  return(prot);
}
Exemplo n.º 18
0
/*----------------------------------------------------------------------+*/
SPC_Connection_Ptr SPC_Lookup_Connection(XeString hostname)
/*----------------------------------------------------------------------+*/
{
  /* Search for an existing connection to a server */
  SPC_Connection_Ptr conn;

  _DtSvcProcessLock();
  for (conn = connection_list; conn != NULL; conn = conn->next) {

    /* Look for a connection with the same hostname */
      if (!strcmp(conn->hostname, hostname)) {
	  _DtSvcProcessUnlock();
	  return(conn);
      }
  }
  
  _DtSvcProcessUnlock();
  return(FALSE);
}
Exemplo n.º 19
0
/*----------------------------------------------------------------------+*/
int
SPC_Initialize(void)
/*----------------------------------------------------------------------+*/
{

  XeString home;

  _DtSvcProcessLock();
  if(SPC_Initialized) {
     _DtSvcProcessUnlock();
     return(TRUE);
  }

  spc_init_fds();

  if (!SPC_ResetTerminator()) {
     _DtSvcProcessUnlock();
     return(SPC_ERROR);
  }
    
  if(!SPC_Init_Local_Host_Info()) {
     _DtSvcProcessUnlock();
     return(SPC_ERROR);
  }

  if(SPC_Setup_Synchronous_Terminator()==SPC_ERROR) {
     _DtSvcProcessUnlock();
     return(SPC_ERROR);
  }

  if(home=getenv("HOME")) {
    spc_user_environment_file=(XeString) XeMalloc(strlen(home)+
		strlen(SPCD_ENV_HOME_DIRECTORY)+strlen(SPCD_ENV_FILE)+3);
    sprintf(spc_user_environment_file, "%s/%s/%s", 
	    home, SPCD_ENV_HOME_DIRECTORY, SPCD_ENV_FILE);
  }
  
  SPC_Initialized=TRUE;
  _DtSvcProcessUnlock();

  return(TRUE);
}
Exemplo n.º 20
0
/*----------------------------------------------------------------------+*/
SPC_Connection_Ptr SPC_Lookup_Connection_Fd(int fd)
/*----------------------------------------------------------------------+*/
{
  /* Search for an existing connection to a server, using fd (file descriptor)
   as a key */
  SPC_Connection_Ptr conn;

  _DtSvcProcessLock();
  for (conn = connection_list; conn != NULL; conn = conn->next) {

    /* Look for a connection with the same hostname */
      if (conn->sid==fd) {
	  _DtSvcProcessUnlock();
	  return(conn);
      }
  }
  
  _DtSvcProcessUnlock();
  return(FALSE);
}
Exemplo n.º 21
0
void 
Dt_nlInit( void )
{
   char * bc;
   static Boolean first = True;

   _DtSvcProcessLock();
   if (!first) {
      _DtSvcProcessUnlock();
      return;
   }

   first = False;
   _DtSvcProcessUnlock();

   if (MB_CUR_MAX > 1)
      _DtNl_is_multibyte = True;
   else
      _DtNl_is_multibyte = False;
}
Exemplo n.º 22
0
/*-----------------------------------------------------------------------+*/
static int
SPC_Select(void )
/*-----------------------------------------------------------------------+*/
{
    break_on_termination=TRUE;

    _DtSvcProcessLock();
    spc_xe_termination_flag= FALSE;

    /* Use a function pointer so we don't have explict dependancy */
    /* on libXe.a						    */
    /* ---------------------------------------------------------- */
    if (SbMainLoopUntil_hookfn == NULL)
      (void) fprintf (stderr, "Error: SbMainLoopUntil = NULL\n");
    else
      (*SbMainLoopUntil_hookfn)(&spc_xe_termination_flag);
    _DtSvcProcessUnlock();

    break_on_termination=FALSE;
    return(TRUE);
}
Exemplo n.º 23
0
/*----------------------------------------------------------------------+*/
int
SPC_ResetTerminator(void)
/*----------------------------------------------------------------------+*/
{
  struct sigaction svect;

  _DtSvcProcessLock();
  if (SPC_who_am_i == SPC_I_AM_A_DAEMON) {
    svect.sa_handler = SPC_Child_Terminated;
    sigemptyset(&svect.sa_mask);
    svect.sa_flags = 0;

    if(sigaction(SIGCHLD, &svect, (struct sigaction *)NULL)==ERROR) {
      SPC_Error(SPC_No_Signal_Handler);
      return(SPC_ERROR);
    }
  }

  _DtSvcProcessUnlock();
  return (TRUE);
}
Exemplo n.º 24
0
/*----------------------------------------------------------------------+*/
SPC_Setup_Synchronous_Terminator(void)
/*----------------------------------------------------------------------+*/
{
  int pipes[2];

  _DtSvcProcessLock();
  if(write_terminator) {
    _DtSvcProcessUnlock();
    return(TRUE);
  }
  
  if(pipe(pipes)<0) {
    SPC_Error(SPC_No_Pipe);
    _DtSvcProcessUnlock();
    return(SPC_ERROR);
  }

  if((write_terminator=SPC_Alloc_Connection())==SPC_ERROR) {
    _DtSvcProcessUnlock();
    return(SPC_ERROR);
  }
  SPC_Add_Connection(write_terminator);
  
  if((read_terminator=SPC_Alloc_Connection())==SPC_ERROR) {
    _DtSvcProcessUnlock();
    return(SPC_ERROR);
  }
  SPC_Add_Connection(read_terminator);

  write_terminator->sid=pipes[WRITE_SIDE];
  write_terminator->connected=TRUE;

  read_terminator->sid=pipes[READ_SIDE];
  read_terminator->connected=TRUE;
  SPC_XtAddInput(NULL, &read_terminator->termination_id, read_terminator->sid,
		 SPC_Conditional_Packet_Handler, SPC_Terminator);
  
  _DtSvcProcessUnlock();
  return(TRUE);
}
Exemplo n.º 25
0
/*-----------------------------------------------------------------------+*/
static int SPC_AddInput(int 			source,
		 SPC_Callback_Condition		condition,
		 SbInputId	 		id)
/*-----------------------------------------------------------------------+*/
{
  SPC_Callback_Struct *structptr = NULL;

  _DtSvcProcessLock();
  if (SPC_Fd_Mapping == NULL) {
    SPC_Fd_Mapping = (SPC_Callback_Struct **) 
	             XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
    memset(SPC_Fd_Mapping, 0, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
  }
  structptr=SPC_LOOKUP_FD_MAPPING(source);

  if(!structptr) {
    structptr=(SPC_Callback_Struct *) XeMalloc(sizeof(SPC_Callback_Struct));
    SPC_LOOKUP_FD_MAPPING(source)=structptr;
  }
  _DtSvcProcessUnlock();

  switch (condition) {

  case SPC_Input:
  case SPC_Terminator:
  case SPC_Client:
    structptr->read_id   = id;
    break;

  case SPC_Exception:
    structptr->except_id = id;
    break;

  default:
    break;
  }

  return(source);
}
Exemplo n.º 26
0
/*----------------------------------------------------------------------+*/
spc_dup2(int from, int to)
/*----------------------------------------------------------------------+*/
{
  int retval;
  
  /* Dup file descriptors.  If a null descriptor, then use /dev/null */
  static int devnull = NULL;

  if (from == to)
    return(TRUE);
  
  if (from == -1) {
    _DtSvcProcessLock();
    if (!devnull)
      devnull = open("/dev/null", 0);
    /* Use /dev/null when no source file descriptor */
    from = devnull;
    _DtSvcProcessUnlock();
  }
  
  /* Now do the dup2 */
  retval=dup2(from, to);
  return(retval);
}
Exemplo n.º 27
0
/******************************************************************************
 *
 * _DtEnvGetTargetCache()
 *
 * For a specified targetHost, find existing cache information and
 * optionally create a cache for a targetHost if one doesn't exist.
 *
 * The define MAX_HOSTS_CACHED controls how many targetHosts can
 * be cached.
 */
static cacheForTargetHost *_DtEnvGetTargetCache(
    char *targetHost,
    int   createIfNeeded)
{
    static int cacheHitGen = 0;
    static int hitIdxStart;
    int i, hitidx, hitval;


    /*
     * Handle obvious.
     */
    if (!targetHost) {
	return( (cacheForTargetHost *) NULL );
    }

    _DtSvcProcessLock();
    /*
     * Look for targetHost in current cache pool.
     */
    for ( i = 0; i < MAX_HOSTS_CACHED; i++ ) {
	if ( cachePoolG[i].remoteHost ) {
	    if ( !strcmp( targetHost, cachePoolG[i].remoteHost ) ) {
		cachePoolG[i].cacheHit++;
		break;
	    }
	}
    }

    if ( i != MAX_HOSTS_CACHED ) {
	/*
	 * targetHost is in a cache slot already.
	 */
	_DtSvcProcessUnlock();
	return( &cachePoolG[i] );
    }
    else if ( !createIfNeeded ) {
	/*
	 * No cache slot for, and we shouldn't create one either.
	 */
	_DtSvcProcessUnlock();
	return( (cacheForTargetHost *) NULL );
    }
    else {
	/*
	 * Find an empty cache slot or take over a rarely used slot.
	 */
	hitIdxStart = (hitIdxStart + 7) % MAX_HOSTS_CACHED;

	hitidx = hitIdxStart;
	hitval = cachePoolG[hitidx].cacheHit;

	for ( i = 0; i < MAX_HOSTS_CACHED; i++ ) {
	    if ( ! cachePoolG[i].remoteHost ) {
		/*
		 * Empty slot - take it.
		 */
		hitidx = i;
		break;
	    }
	    else if ( cachePoolG[i].cacheHit < hitval ) {
		hitidx = i;
		hitval = cachePoolG[i].cacheHit;
	    }
	}

	if ( cachePoolG[hitidx].remoteHost ) {
	    /*
	     * Cache was in use, clean first.
	     */
	    _DtEnvCleanCacheSlot( &cachePoolG[hitidx] );
	    cachePoolG[hitidx].remoteHost = strdup( targetHost );

	    /*
	     * Since all the slots are full, occasionally reset everyones
	     * cacheHit counters.   This gives new targetHosts a chance
	     * to compete with targetHosts that were popular long ago.
	     */
	    if ( cacheHitGen++ > 50 ) {
		for ( i = 0; i < MAX_HOSTS_CACHED; i++ ) {
		    cachePoolG[i].cacheHit = 1;
		}
		cacheHitGen = 1;
	    }
	}
	_DtSvcProcessUnlock();
	return( &cachePoolG[hitidx] );
    }
}
Exemplo n.º 28
0
char *_DtEnv_tt_host_netfile_file(
    const char *host,
    const char *filename)
{
    static int             first_time  = 1;
    static int             fragListAvail = CACHE_FILEFRAG_SIZE_START;
    static int             fragListCnt = 0;
    static cachedNetfileFrag *fragList;
    static int             cacheGen = 0;
    static int             hitIdxStart = 0;

    char           *newfile;
    int             hitval, hitIdx, i;
    cachedNetfileFrag *tmpCffP;
    char           *tmpStr;
    int            newCount = fragListCnt;

    _DtSvcProcessLock();
    if (first_time) {
	fragList = (cachedNetfileFrag *) calloc( fragListAvail,
						sizeof(cachedNetfileFrag) );
	first_time = 0;
    }

    /*
     * Take care of the obvious.
     */
    if (!filename) {
	_DtSvcProcessUnlock();
	return( (char *) NULL );
    }

    if (!host) {
	/*
	 * Return a tt_free-able un-mapped copy.
	 */
	tmpStr = tt_malloc( strlen(filename) + 1 );
	strcpy( tmpStr, filename );

	_DtSvcProcessUnlock();
	return(tmpStr);
    }

    /*
     * Look for existing answer in cache.
     *
     * While at it, also look for least used entry just in case.
     */
    if (fragListCnt)
	hitIdxStart = (hitIdxStart + 7) % fragListCnt;
    else
	hitIdxStart = 0;

    hitIdx = hitIdxStart;
    hitval = fragList[hitIdx].cacheHit;
    tmpCffP = fragList;				/* walk rather than index */

    for ( i = 0; i < fragListCnt; i++ ) {
	if (tmpCffP->cacheHit && !strcmp( filename, tmpCffP->pathFragOrig ) ) {
	    if (!strcmp( host, tmpCffP->targetHost ) ) {
		break;
	    }
	}

	/*
	 * Save index of least used entry
	 */
	if (tmpCffP->cacheHit < hitval) {
	    hitIdx = i;
	    hitval = tmpCffP->cacheHit;
	}
	tmpCffP++;
    }

    /*
     * Decide what was found.
     */
    if ( i != fragListCnt ) {
	/*
	 * Found a cached entry.
	 */
	hitIdx = i;
	if ( fragList[hitIdx].cacheHit++ > CACHE_FILEFRAG_REMAP_AFTER ) {
	    /*
	     * This looks like an old entry, so re-compute it.
	     */
	    freeAndNull( fragList[hitIdx].targetHost );
	    freeAndNull( fragList[hitIdx].pathFragOrig );
	    ttfreeAndNull( fragList[hitIdx].pathFragMapped );
	    fragList[hitIdx].cacheHit = 0;	/* 0 means remap below */
	}
    }
    else {
	/*
         * Did not find a cache entry, so scrounge around for
	 * a new entry.
	 */
	if ( fragListCnt < fragListAvail ) {
	    /*
	     * Use next already-malloc'ed cacheEntry.
	     */
	    hitIdx = fragListCnt;
            newCount = fragListCnt + 1;
	}
	else if ( fragListCnt < CACHE_FILEFRAG_SIZE_MAX ) {
	    /*
	     * Can grow fragList[]
	     */
	    fragListAvail += CACHE_FILEFRAG_SIZE_BUMP;
	    fragList = (cachedNetfileFrag *) realloc( (char *) fragList,
					sizeof(cachedNetfileFrag) * fragListAvail);
	    /*
	     * Zero out new memory.
	     */
	    memset( fragList + (fragListAvail-CACHE_FILEFRAG_SIZE_BUMP),
		    0, CACHE_FILEFRAG_SIZE_BUMP*sizeof(cachedNetfileFrag) );
	    hitIdx = fragListCnt;
            newCount = fragListCnt + 1;
	}
	else {
	    /*
	     * Last resort - bump out the least used entry.
	     */
	    freeAndNull( fragList[hitIdx].targetHost );
	    freeAndNull( fragList[hitIdx].pathFragOrig );
	    ttfreeAndNull( fragList[hitIdx].pathFragMapped );

	    /*
	     * Since the cache is 100% full, ocassionally reset
	     * everyone's cacheHit rate so entries that were only
	     * popular long ago don't get locked in.
	     */
	    if ( cacheGen++ > CACHE_FILEFRAG_RESET_PRI ) {
		cacheGen = 0;
		tmpCffP = fragList;
		for ( i = 0; i < fragListCnt; i++ ) {
		    tmpCffP->cacheHit = 1;
		    tmpCffP++;
		}
	    }
	}

	fragList[hitIdx].cacheHit = 0;		/* 0 means remap below */
    }

    if ( ! fragList[hitIdx].cacheHit ) {
	/*
	 * Need to perform mapping.
	 */
	newfile = tt_host_netfile_file( host, filename );

#ifdef _DTENV_SUPPORT_MAPERROR_CACHING
	fragList[hitIdx].targetHost = strdup ( host );
	fragList[hitIdx].pathFragOrig = strdup( filename );
	fragList[hitIdx].cacheHit = 1;
	fragList[hitIdx].pathFragMapped = newfile;

        fragListCnt = newCount;
#else
	if ( tt_ptr_error(newfile) == TT_OK ) {
	    fragList[hitIdx].targetHost = strdup ( host );
	    fragList[hitIdx].pathFragOrig = strdup( filename );
	    fragList[hitIdx].cacheHit = 1;
	    fragList[hitIdx].pathFragMapped = newfile;
            /*
             * Only change the count if we are successful in adding 
             * a new entry.
             */
            fragListCnt = newCount;
	}
	else {
	    /*
	     * Don't cache errors.   Leave this cache slot empty
	     * and it will be rediscovered and used in the future.
	     */
	    fragList[hitIdx].cacheHit = 0;

	    /*
	     * Do not change the fragListCount since we are not saving
	     * error entries.
	     */
	}
#endif /* _DTENV_SUPPORT_MAPERROR_CACHING */
    }

    /*
     * Dig out answer and return it.
     */
#ifdef _DTENV_SUPPORT_MAPERROR_CACHING
    if ( tt_ptr_error(newfile) == TT_OK )
#else
    if ( fragList[hitIdx].cacheHit )
#endif /* _DTENV_SUPPORT_MAPERROR_CACHING */
    {
	/*
	 * Return a tt_free-able copy of the answer.
	 */
	tmpStr = tt_malloc( strlen(fragList[hitIdx].pathFragMapped) + 1 );
	strcpy( tmpStr, fragList[hitIdx].pathFragMapped );

	_DtSvcProcessUnlock();
	return(tmpStr);
    }
    else {
	/*
	 * See XXX comment.
	 *
	 * Since newfile is an error code, return as is.
	 */ 
	_DtSvcProcessUnlock();
	return(newfile);
    }
}
Exemplo n.º 29
0
/* This is the right way according to the Spec 1170 */
void SPC_Child_Terminated(int i)
/*----------------------------------------------------------------------+*/
{
  /* This catches signals for sub-process termination */
  int type, cause, status;
  pid_t wait_pid, pid;
  SPC_Channel_Ptr channel;
  protocol_request     req, *prot;
  buffered_data        data, *pdata;
  int length;
  int indx;
  int saved_errno = errno;

  prot  = (&req);
  pdata = (&data);

  prot->dataptr=pdata;

  wait_pid = -1;
  while(pid = waitpid(wait_pid, &status, WNOHANG)) {
    if((pid == -1 && errno == ECHILD) || pid == 0) {
      /* no more children.  Return */
      errno = saved_errno;
      return;
    }
    
    /* Okay, we got the process ID of a terminated child.  Find the
       channel associated with this PID. */
    channel=SPC_Find_PID(pid);
#ifdef DEBUG
    fprintf(stderr, (XeString)"got SIGCHLD, pid: %d, channel: %p\n", pid, channel);
#endif

    if(!channel) {
      continue;
    }

    _DtSvcProcessLock();
    /*
     * Look for this process in the pid list.  If found, mark it
     * as done.
     */
    if (SPC_pid_list != NULL) {
      for (indx=0; SPC_pid_list[indx] != NULL; indx++)
        if (SPC_pid_list[indx] == pid) {
	   SPC_pid_list[indx] = SPCD_DEAD_PROCESS;
	   break;
	}
    }
    _DtSvcProcessUnlock();

    /* We have the channel.  Mark it as being closed. */

    channel->status     = status;

    /* If we this channel is set up for synchronous termination,
       write the protocol request to record that this guy died.
       Otherwise, call the termination handler directly. */
    
    if(IS_SPCIO_SYNC_TERM(channel->IOMode)) {

      /* This code is basically what SPC_Write_Protocol_Request does.
	 It is replicated here because a call to SPC_W_P_R would have
	 to be re-enterant if we called it here, and SPC_W_P_R is not
	 re-enterant at this time. */
      
      SPC_Reset_Protocol_Ptr(prot, channel, APPLICATION_DIED, 0);
      pdata->len=WRITE_APPLICATION_DIED(pdata, status);
      length=WRITE_HEADER(pdata, channel->cid,
			  prot->request_type,
			  pdata->len,
			  0);
      pdata->data[length]=(XeChar)' ';
      length=pdata->len+REQUEST_HEADER_LENGTH;
      if(write(write_terminator->sid, pdata->data, length)==ERROR)
	SPC_Error(SPC_Internal_Error);
      pdata->offset=REQUEST_HEADER_LENGTH;
      print_protocol_request((XeString) (XeString)"  <-- INTERNAL APPLICATION_DIED", prot);
    }
    else {
      SPC_Change_State(channel, NULL, -1, 0);
      if(channel->Terminate_Handler) {
	XeSPCGetProcessStatus(channel, &type, &cause);
	(* channel->Terminate_Handler)
	  (channel, channel->pid, type, cause, channel->Terminate_Data);
      }
    }
    /* Loop around & get another PID */
  }
  errno = saved_errno;
}
Exemplo n.º 30
0
/*----------------------------------------------------------------------+*/
int exec_proc_local_channel_object(SPC_Channel_Ptr channel)
/*----------------------------------------------------------------------+*/
{
    sigset_t newsigmask, oldsigmask;
    pid_t pid;
    int result;
    XeString *envp;
    XeString dir = XeString_NULL;
    int retval;
    int i, reuse_pid = 0;
    
    call_parent_method(channel, exec_proc, (channel), result);
    
    if(result==SPC_ERROR)
	return(SPC_ERROR);

    /* Check to see if the channel pathname points to a valid executable.
       We do this by using the _path_search function.  If the channel
       has a PATH variable set in its local environment, use it,
       otherwise use the "global" environment.  We can accomplish this
       by using the spc_getenv call in the _path_search call.  If the
       channel doesn't have a PATH variable, then spc_getenv will
       return NULL, which indicates use of the global environment.
   */

    if(!_path_search(SPC_Getenv("PATH", channel->envp),
		    channel->path,
		    executable_predicate)) {
      SPC_Error(SPC_Cannot_Exec, channel->path);
      return(SPC_ERROR);
    }
       
    /* If we were passed a host:dir to cd to, make sure it exists. */
    /* We want to do this before we fork the child.                */

    if((channel->context_dir) && (channel->context_dir[0])) {
	struct stat	stat_info;
	Boolean ok = FALSE;
	
	_DtSvcProcessLock();
	if (SPC_client_version_number < SPC_PROTOCOL_VERSION_CDE_BASE)
	   dir = get_path_from_context(channel->context_dir);
	else {
	   /*
	    * context_dir is actually a "netfile" so it needs to
	    * be converted to a "real" path.
	    */
	   dir = (char *) tt_netfile_file (channel->context_dir);
	   if (tt_ptr_error (dir) != TT_OK) 
	      dir = NULL;
	}
	_DtSvcProcessUnlock();

	if (dir == NULL)
	    /* can't make connection ... */;
	else if (stat(dir,&stat_info) != 0)	
	    /* directory not there */;

	else if ((stat_info.st_mode & S_IFDIR) == 0)
	    /* path is not a directory ... */;
	else
	    ok = TRUE;
	
	if (!ok && IS_SPCIO_FORCE_CONTEXT(channel->IOMode)) {
	    if (dir != NULL && (strcmp (dir, channel->context_dir) != 0))
	       SPC_Error(SPC_cannot_Chdir, dir);
	    SPC_Error(SPC_cannot_Chdir, channel->context_dir);
	    XeFree(dir);
	    dir = XeString_NULL;
	    return(SPC_ERROR);
	}
    }

    if(mempf0(channel, pre_fork)==SPC_ERROR)
	return(SPC_ERROR);
    
    /* When using HP NLIO (xj0input) we have a problem.  Namely,  */
    /* the xj0 processs uses signal() to deal with SIGCLD which   */	
    /* is incompatible with sigaction/sigprogmask/etc.  Even      */
    /* though xj0 resets the signal handler, since the signal     */
    /* routines are incompatible, our original handler gets lost. */
    /* Hence, we need to reset it.  We do it here everytime we    */
    /* fork a child just to be on the safe side.                  */

    SPC_ResetTerminator();
    
    sigemptyset(&newsigmask);
    sigemptyset(&oldsigmask);
    sigaddset(&newsigmask, SIGCHLD);
    
    if (sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask) == ERROR)
	return(SPC_ERROR);
    
    pid = channel->pid = fork();
    
    /*
     * Must save this pid so that when the daemon's timer goes off,
     * if there has been no activity and there are no sub-processes
     * running, the daemon can exit.
     */
    i = 0;
    _DtSvcProcessLock();
    if (SPC_pid_list == NULL)
      /*
       * Create the first block plus the NULL terminator.
       */
      SPC_pid_list = (pid_t *) malloc (2 * sizeof (pid_t));
    else {
      /*
       * If a dead pid entry exists, reuse it; otherwise, must create 
       * room for the new pid.
       */
      for (i = 0; SPC_pid_list[i] != NULL; i++)
        if (SPC_pid_list[i] == SPCD_DEAD_PROCESS) {
	  SPC_pid_list[i] = pid;
	  reuse_pid = 1;
	  break;
	}
      if (!reuse_pid)
	SPC_pid_list = (pid_t *) realloc (SPC_pid_list, 
					   (i+2) * sizeof (pid_t));
    }
    if (!reuse_pid) {
      SPC_pid_list[i] = pid;
      SPC_pid_list[i+1] = NULL;
    }
    _DtSvcProcessUnlock();

    if (pid) {
	XeFree(dir);
	
	/* Did we really fork? */
	if (pid == ERROR) {
	  SPC_Error(SPC_Cannot_Fork);
	  retval = SPC_ERROR;
	} else {
	  /* Do any set up for the parent process here */
	  mempf1(channel, post_fork, pid);
	  retval = TRUE;
	}
	
	/* Reinstate the old signal mask (unblock SIGCLD). */
	
	sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
	return(retval);
    }
    else {
	/* Child process: connect wires, make environment and exec sub-process */
	
	sigprocmask(SIG_SETMASK, &oldsigmask, (sigset_t *)NULL);
	
	/* Make sure the child is the process group leader.  In the case of
	   ptys, we also want to break the current terminal affiliation.
	   We want to be the process group leader so XeSPCKillProcess (which
	   does a kill(-pid, 9)) will kill all processes associated with us.
	   
	   For PTY's, we need to break the terminal affiliation so the next
	   open (which will be a pty) will cause us to become affiliated with
	   the pty.  We do this so when the parent process closes the master
	   side of the pty, the slave side processes get SIGHUP.  If they
	   ignore SIGHUP, they will never die.  So it goes...
	   */

	if(IS_SPCIO_PTY(channel->IOMode))
	    setsid();
	else {
	    pid_t tmppid = getpid();
	    if(setpgid(tmppid, tmppid) == -1) 
		fprintf(stderr, (XeString)"setpgid failed, errno: %d\n", errno);
	}
	
	/* Connect wires to sub-process standard files */
	result=mempf1(channel, post_fork, pid);
	
	if(result!=SPC_ERROR) {
	    int		indx = -1;
	    int		i;
	    char	**ppch;

	    /*
	     * Before adding in the list of environment variables 
	     * from the environment variable files, must search 
	     * the list for LANG definitions.  If found, the
	     * last definition must be putenv'ed to assure the 
	     * multi-byte parsing code is using the correct locale.
	     */
	    for (i = 0, ppch = channel->envp; *ppch; *ppch++, i++)
	       if (!strncmp (*ppch, "LANG=", 5))
		  indx = i;

	    if (indx != -1)
	       resolve_variable_reference (&channel->envp[indx]);

	    _DtSvcProcessLock();
	    if (!setlocale (LC_CTYPE, ""))
	       /*
		* setlocale failed - log a message but execute 
		* the command anyway.
		*/ 
	       if (SPC_Print_Protocol != NULL)
		  (void) fprintf(SPC_Print_Protocol,
		      "+++> Failed to 'setlocale'; LANG = %s\n",
		      getenv("LANG"));
	    /* Mix in the stashed environment */
	    
	    for(envp=channel->envp; *envp; envp++)
		resolve_variable_reference(&*envp);

	    if (SPC_mount_point_env_var != NULL)
		/*
		 * The mount point environment variable was 
		 * inherited by the daemon or was given to the
		 * daemon via the command line.  In either case
		 * this subprocess must inherit the daemon's
		 * value.
		 */
		(void) putenv (SPC_mount_point_env_var);
	    _DtSvcProcessUnlock();

	    /* Connect to the context directory */
	    /* We have already validated this guy exists */

	    if(dir) 
		Xechdir(dir);
	}
	
	XeFree(dir);

	if(result!=SPC_ERROR) {
	    /* Execute */
	    /* Compiler barfs without cast ? */
#if defined(__hpux_8_0) || defined(__aix)
            result=execvp(channel->path, channel->argv);
#else
	    result=execvp(channel->path, channel->argv);
#endif
	    /* If we return from exec, it failed */
	    SPC_Error(SPC_Cannot_Exec, channel->path);
	}
	
	/* We want to get rid of this child image (carefully) */
	_exit(42);
	
    }
}