Пример #1
0
static void ParseMasterArgs(netadr_t *broadcast)
{
    void *data;
    ssize_t len;
    void (*parse)(void *, size_t, size_t);
    size_t chunk;
    char *s, *p;
    int i, argc;

    Cmd_TokenizeString(m_servers.args, qfalse);

    argc = Cmd_Argc();
    if (!argc) {
        // default action to take when no URLs are given
        ParseAddressBook();
        broadcast->type = NA_BROADCAST;
        broadcast->port = BigShort(PORT_SERVER);
        return;
    }

    for (i = 0; i < argc; i++) {
        s = Cmd_Argv(i);
        if (!*s)
            continue;

        // parse binary format specifier
        parse = ParsePlain;
        chunk = 0;
        if (*s == '+' || *s == '-') {
            parse = ParseBinary;
            chunk = strtoul(s, &p, 10);
            if (s == p) {
                chunk = 6;
                s = p + 1;
            } else {
                if (chunk < 6)
                    goto ignore;
                s = p;
            }
        }

        if (!strncmp(s, "file://", 7)) {
            len = FS_LoadFile(s + 7, &data);
            if (len < 0)
                continue;
            (*parse)(data, len, chunk);
            FS_FreeFile(data);
            continue;
        }

        if (!strncmp(s, "http://", 7)) {
#if USE_CURL
            len = HTTP_FetchFile(s + 7, &data);
            if (len < 0)
                continue;
            (*parse)(data, len, chunk);
            Z_Free(data);
#else
            Com_Printf("Can't fetch '%s', no HTTP support compiled in.\n", s);
#endif
            continue;
        }

        if (!strncmp(s, "favorites://", 12)) {
            ParseAddressBook();
            continue;
        }

        if (!strncmp(s, "broadcast://", 12)) {
            broadcast->type = NA_BROADCAST;
            broadcast->port = BigShort(PORT_SERVER);
            continue;
        }

        if (!strncmp(s, "quake2://", 9)) {
            AddServer(NULL, s + 9);
            continue;
        }

ignore:
        Com_Printf("Ignoring invalid master URL: %s\n", s);
    }
}
Пример #2
0
/*
** CreateAsc( ) --- Create an association.
**
** Inputs:
**	asipc	ASSOC_IPC for association
**	name	name of server creating association.
** Output:
**	returns TRUE if succeeds.
**
** GClisten( ) calls CreateAsc( ) when a server wishes to create
** a new association. CrateAsc( ) allocates the resources required by 
** the association, and exposes shared information available to other processes.
** The only requirements are that it create four handles in the ASSOC_IPC:
** standard send, standard receive, expedited send, and expeditied receive.
** These handles are the only members created here used by gcacl. In 
** this implementation handles to anonymous pipes are used.
**
** If there are no existing connections to the server spicified in the 
** name parameter, CreateAsc( ) creates the server specific resources and
** adds the server to the internally maintained list of servers. A memory mapped
** mapped file is created for passing information between the client and 
** server. This file contains a temporary area for passing process id and
** handles which the client needs to copy to its own ASSOC_IPC. It also 
** contains and array of assoc_info structures. These structures contain
** information that must be shared per connection for the duration of each 
** association. A mutex is created to protect access to the temporary area.
** The temporary area is only used when a connectionis first established
** to copy handles to the pipes and other information to the requester's
** ASSOC_IPC.
**
** Two events are also created to arbitrate the connection process. When
** a server is ready for a connection, it signals a "listening event". 
** and waits for a client to set a requesting event. Before connecting 
** a client waits on the listening event before trying to connect. When
** the client tries to connect it sets a requesting event to tell the server
** that a client has connected.
**
** The names for the memory mapped file, the mutex, and the events are
** based on the server name.
**
** History:
**      10-Dec-98 (lunbr01) Bug 94183
**          Eliminate use of *Ct fields (using PeekNamedPipe instead).
*/
BOOL 	 
CreateAsc(ASSOC_IPC * asipc, char *name )
{
	HANDLE 		hMapping; /* for memory mapped file */
	static HANDLE	hMutex;	  /* for memory mapped file */
	ASSOC_IPC	*asipc_temp;
	ASSOC_INFO	*assoc_info;
	struct _Asc_ipc_area	*svr_ipc_area;
	SERVER_ENTRY	*server;
	short		i;
															
	SECURITY_ATTRIBUTES	sa;
	
	/* Set up security attributes */		
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	
	/* If there are no existing connections to this server. Open the
	** memory mapped file, events, and mutex for this server. 
	*/
	if( NULL == ( server = LookUpServer( name ) ) )	
	{
		char ReqEventName[MAXPNAME + 4 ];
		char LstEventName[MAXPNAME + 4 ];
		
		if ((hMapping = CreateFileMapping(INVALID_HANDLE_VALUE,
				&sa,
				PAGE_READWRITE,
				0,
				sizeof( struct _Asc_ipc_area ),  
				name )) == NULL)
		{
			DWORD err = GetLastError( );
			return FALSE ;
		}
		
		if (NULL == (svr_ipc_area=
			(struct _Asc_ipc_area *)MapViewOfFile(hMapping,
						FILE_MAP_ALL_ACCESS,
						0,
						0,
						0 ) ) )
		{
			return FALSE;
		}
		
		/* Create an event that will be signaled when an 
		** association is requested.
		*/
		wsprintf( ReqEventName, "%s-%s", name, "req" );
		wsprintf( LstEventName, "%s-%s", name, "lst" );
		
		/* Create SERVER_ENTRY */
		server = AddServer( name,  svr_ipc_area, hMapping, 
					CreateEvent( &sa, FALSE, FALSE, 
					ReqEventName ), 
					CreateEvent( &sa, FALSE, FALSE, 
					LstEventName ) );
		
		/* Create a mutex to coordinate access to asipc_temp */
		hMutex = CreateMutex( &sa, FALSE, name );
		
		/* Create a proces handle so other processes can 
		   use DuplicateHandle */
		svr_ipc_area->nProcId =  GetCurrentProcessId( );
	}
	
	/* Get a pointer to the Memory mapped file for this server. */
	svr_ipc_area = server->lpMapping;
	
	if ( server->nConnections == MAX_ASSOCS ) /* no more assocs allowed */
		return FALSE ;
		
	asipc_temp = &( svr_ipc_area->asipc );
	assoc_info = (ASSOC_INFO *)&( svr_ipc_area->assoc_info );

	/* Make sure that it is safe to change temporary connection info.  
	** Copy the connection information the local ASSOC_IPC. 
	*/
	WaitForSingleObject( hMutex, INFINITE );	
	
	/* Find a valid id and set up the assoc_info. */
	for( i = 0; i < MAX_ASSOCS; i++ )
	{
		if ( assoc_info[i].refs == 0 )
			break;
	}
	asipc->IpcInternal.hMapping 	= hMapping; /* for save and restore */
	asipc->IpcInternal.AssocInfo	= &assoc_info[i];
	asipc_temp->IpcInternal.AscID	= asipc->IpcInternal.AscID = i;
	assoc_info[i].bPipesClosed = FALSE;
	assoc_info[i].refs++;

	/* Set the AssocInfo */

	assoc_info[i].out_buffer_size = Pipe_buffer_size;
	assoc_info[i].in_buffer_size = Pipe_buffer_size;

	if(!CreatePipe( &asipc->RcvStdChan, &asipc_temp->SndStdChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc_temp->RcvStdChan, &asipc->SndStdChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc->RcvExpChan, &asipc_temp->SndExpChan, &sa, 
				Pipe_buffer_size ) ||
	   !CreatePipe( &asipc_temp->RcvExpChan, &asipc->SndExpChan, &sa, 
				Pipe_buffer_size ) ) 
	{
		CloseAsc( asipc );
		CloseAsc( asipc_temp );
		return FALSE ;
	}

        /* We need to duplicate the client side of standard read handle
           asipc_temp->RcvStdChan for PeekNamedPipe() because it gets closed
           by the DUPLICATE_CLOSE_SOURCE option of DuplicateHandle() after a
           front end client connects to the server and duplicates it into
           their address space. */
        if (!DuplicateHandle(
                       GetCurrentProcess(),
                       asipc_temp->RcvStdChan,
                       GetCurrentProcess(),
                       &asipc->ClientReadHandle,
                       GENERIC_READ,
                       TRUE,
                       DUPLICATE_SAME_ACCESS
                       ) )
        {
                        CloseAsc( asipc );
                        CloseAsc( asipc_temp );
                        return FALSE ;
        }

        /* We need to duplicate the server side of standard read handle
           asipc->RcvStdChan for PeekNamedPipe() in the client because it
           gets closed by the DUPLICATE_CLOSE_SOURCE option of
           DuplicateHandle() after a front end client connects to the server
           and duplicates it into their address space. */
        if (!DuplicateHandle(
                       GetCurrentProcess(),
                       asipc->RcvStdChan,
                       GetCurrentProcess(),
                       &asipc_temp->ClientReadHandle,
                       GENERIC_READ,
                       TRUE,
                       DUPLICATE_SAME_ACCESS
                       ) )
        {
                        CloseAsc( asipc );
                        CloseAsc( asipc_temp );
                        return FALSE ;
        }

	ReleaseMutex( hMutex );

	/* 
	** Set up pointer to server and increment the number of connections.	
	*/
	asipc->IpcInternal.server = server;
	asipc->IpcInternal.server->nConnections++;
		
	return TRUE;
}
Пример #3
0
STATUS 	 
OpenAsc(ASSOC_IPC * asipc, char *name, DWORD timeout )
{
	HANDLE			hMapping;
	HANDLE			hMutex;
	HANDLE			hSrcProc;
	struct _Asc_ipc_area	*cli_ipc_area;
	SERVER_ENTRY		*server;

	/* 
	** If there are no connections to this server, set up a 
	** SERVER_ENTRY and open the required resources.	
	*/
	if ( NULL == ( server = LookUpServer( name) ) )
	{
	    char ReqEventName[MAXPNAME + 4 ];/*Event for requesting connection*/
	    char LstEventName[MAXPNAME + 4 ];/*Event to see server is lstning */
	    HANDLE revent, levent;
		
	    /* Create an event that will be signaled when an 
	    ** association is requested. */
	    wsprintf( ReqEventName, "%s-%s", name, "req" );
	    wsprintf( LstEventName, "%s-%s", name, "lst" );
		
	    if( NULL == (revent = OpenEvent( EVENT_ALL_ACCESS, 
						FALSE, ReqEventName ) ) )
		return ~OK;
			
	    if( NULL == (levent = OpenEvent( EVENT_ALL_ACCESS, 
						FALSE, LstEventName ) ) )
	    {
		CloseHandle( revent );
		return ~OK;
	    }
			
	    if( NULL == (hMapping = OpenFileMapping( FILE_MAP_ALL_ACCESS, 
						TRUE, name ) ) )
	    {
		CloseHandle( levent );
		CloseHandle( revent );
		return ~OK;
	    }
			
	    if ( NULL == ( cli_ipc_area = (struct _Asc_ipc_area *)
					MapViewOfFile(	hMapping,
					  	FILE_MAP_ALL_ACCESS,
		  				0,
		  				0,
		  				0 ) ) )
	    {
		CloseHandle( hMapping );
		CloseHandle( levent );
		CloseHandle( revent );
		return~OK;
	    }
	
	    if ( PCis_alive( cli_ipc_area->nProcId ) == FALSE )
	    {
		UnmapViewOfFile( hMapping );
		CloseHandle( hMapping );
		CloseHandle( levent );
		CloseHandle( revent );
		return ~OK;
	    }
		
		
	    /* Create SERVER_ENTRY */
	    server = AddServer( name,  cli_ipc_area, hMapping, revent, levent );
	}

	/* Get pointer to memory mapped file with shared data.	*/
	cli_ipc_area = server->lpMapping;
	
	/* wait for a server to listen. */
	if( WAIT_TIMEOUT == WaitForSingleObject( server->ListeningEvent, 
		timeout == GC_WAIT_FOREVER ? INFINITE : timeout ) )
	{
		return GC_TIME_OUT;
	}

	/*
	** Setup the ASSOC_IPC
	*/	
	hMutex = OpenMutex( MUTEX_ALL_ACCESS, TRUE, name );
	WaitForSingleObject( hMutex, INFINITE );
	
	asipc->IpcInternal.hMapping = server->hMapping;	/*for save and restore*/
	asipc->IpcInternal.AscID = cli_ipc_area->asipc.IpcInternal.AscID;
	asipc->IpcInternal.AssocInfo = &cli_ipc_area->assoc_info[asipc->IpcInternal.AscID];
	/* Increment Reference Count for AssocInfo */
	asipc->IpcInternal.AssocInfo->refs++;
       
	hSrcProc = OpenProcess( PROCESS_DUP_HANDLE, TRUE, cli_ipc_area->nProcId );

	/* Get the pipe handles. */
	if (!DuplicateHandle( hSrcProc,
				cli_ipc_area->asipc.SndStdChan,
				GetCurrentProcess( ),
				&asipc->SndStdChan,
				GENERIC_READ | GENERIC_WRITE,
				TRUE,
				DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS ) )
	{
		CloseAsc( asipc );
		return ~OK;

	}
	
	if (!DuplicateHandle( hSrcProc, 
				cli_ipc_area->asipc.RcvStdChan,
				GetCurrentProcess( ),
				&asipc->RcvStdChan,
				GENERIC_READ | GENERIC_WRITE,
				TRUE,
				DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS) )
	{
		CloseAsc( asipc );
		return ~OK;
	}
	
	if (!DuplicateHandle( hSrcProc, 
				cli_ipc_area->asipc.SndExpChan,
				GetCurrentProcess( ),
				&asipc->SndExpChan,
				GENERIC_READ | GENERIC_WRITE,
				TRUE,
				DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS ) )
	{
		CloseAsc( asipc );
		return ~OK;
	}
	
	if (!DuplicateHandle( hSrcProc, 
				cli_ipc_area->asipc.RcvExpChan,
				GetCurrentProcess( ),
				&asipc->RcvExpChan,
				GENERIC_READ | GENERIC_WRITE,
				TRUE,
				DUPLICATE_CLOSE_SOURCE|DUPLICATE_SAME_ACCESS ) ) 
	{
		CloseAsc( asipc );
		return ~OK;
	}

        if (!DuplicateHandle( hSrcProc,
                                cli_ipc_area->asipc.ClientReadHandle,
                                GetCurrentProcess( ),
                                &asipc->ClientReadHandle,
                                GENERIC_READ | GENERIC_WRITE,
                                TRUE,
                                DUPLICATE_CLOSE_SOURCE) )
        {
                CloseAsc( asipc );
                return ~OK;
        }
	
	/* Set the handles in the temporary area to NULL before 
	** releaseing mutex so no one else steals them.	
	*/
	cli_ipc_area->asipc.SndStdChan = NULL;
	cli_ipc_area->asipc.RcvStdChan = NULL;
	cli_ipc_area->asipc.SndExpChan = NULL;
	cli_ipc_area->asipc.RcvExpChan = NULL;
	cli_ipc_area->asipc.ClientReadHandle = NULL;

	/* Point AssocInfo to propper structure in shared memory. */
	asipc->IpcInternal.AssocInfo = &( cli_ipc_area->assoc_info[asipc->IpcInternal.AscID] );
	
        /* Set flag to indicate Pipe is open */
        asipc->IpcInternal.AssocInfo->bPipesClosed = FALSE;

	ReleaseMutex( hMutex );
	CloseHandle( hMutex );

	/* Tell the server that we are ready to request a connection. */
	SetEvent( server->RequestingEvent );
	
	server->nConnections++;
	asipc->IpcInternal.server = server;
								  
	return OK;
}
Пример #4
0
static void
ProcessLine(char *Linebuf)
{
    char *Directive;
    char *Param1;
    char *Param2;
    char *Param3;

    /* Ignore empty lines */
    if (strlen(Linebuf) == 0)
	return;

    /* Break up on whitespaces */
    if ((Directive = strtok(Linebuf, " \t\n")) == NULL)
	return;

    /* Check for a comment line. If found, stop . */
    if (Directive[0] == '#')
	return;

    /* Check for server line. Check for 3 parameters. */
    if (strcasecmp(Directive, "server") == 0) {
	Param1 = strtok(NULL, " \t\n");
	if (NULL == Param1) {
	    syslog(LOG_ERR, "ProcessLine: 'server' missing PDC parameter.");
	    return;
	}
	Param2 = strtok(NULL, " \t\n");
	if (NULL == Param2) {
	    syslog(LOG_ERR, "ProcessLine: 'server' missing BDC parameter.");
	    return;
	}
	Param3 = strtok(NULL, " \t\n");
	if (NULL == Param3) {
	    syslog(LOG_ERR, "ProcessLine: 'server' missing domain parameter.");
	    return;
	}
	AddServer(Param1, Param2, Param3);
	return;
    }
    /* Check for denyusers line */
    if (strcasecmp(Directive, "denyusers") == 0) {
	Param1 = strtok(NULL, " \t\n");

	if (NULL == Param1) {
	    syslog(LOG_ERR, "ProcessLine: A 'denyusers' line needs a filename parameter.");
	    return;
	}
	memset(Denyuserpath, '\0', MAXPATHLEN);
	strncpy(Denyuserpath, Param1, MAXPATHLEN - 1);
	return;
    }
    /* Check for allowusers line */
    if (strcasecmp(Directive, "allowusers") == 0) {
	Param1 = strtok(NULL, " \t\n");

	if (NULL == Param1) {
	    syslog(LOG_ERR, "ProcessLine: An 'allowusers' line needs a filename parameter.");
	    return;
	}
	memset(Allowuserpath, '\0', MAXPATHLEN);
	strncpy(Allowuserpath, Param1, MAXPATHLEN - 1);
	return;
    }
    /* Reports error for unknown line */
    syslog(LOG_ERR, "ProcessLine: Ignoring '%s' line.", Directive);
}