Ejemplo n.º 1
0
/*
** Parse a text URI into an HtmlUri structure.
*/
static HtmlUri *ParseUri(const char *zUri){
  HtmlUri *p;
  int n;

  p = HtmlAlloc( sizeof(*p) );
  if( p==0 ) return 0;
  memset(p, 0, sizeof(*p));
  if( zUri==0 || zUri[0]==0 ) return p;
  while( isspace(zUri[0]) ){ zUri++; }
  n = ComponentLength(zUri, "", ":/?# ");
  if( n>0 && zUri[n]==':' ){
    p->zScheme = StrNDup(zUri, n);
    zUri += n+1;
  }
  n = ComponentLength(zUri, "//", "/?# ");
  if( n>0 ){
    p->zAuthority = StrNDup(&zUri[2], n-2);
    zUri += n;
  }
  n = ComponentLength(zUri, "", "?# ");
  if( n>0 ){
    p->zPath = StrNDup(zUri, n);
    zUri += n;
  }
  n = ComponentLength(zUri, "?", "# ");
  if( n>0 ){
    p->zQuery = StrNDup(&zUri[1], n-1);
    zUri += n;
  }
  n = ComponentLength(zUri, "#", " ");
  if( n>0 ){
    p->zFragment = StrNDup(&zUri[1], n-1);
  }
  return p;
}
Ejemplo n.º 2
0
INLINE STRPTR GetTaskName( struct Task *task, UWORD *namelen )
{
	struct Process *pr = (struct Process *) task;
	STRPTR name = NULL;
	
//	ENTER();
//	DBG_POINTER(task);
	
	#define b2c(x) ( x << 2 )  /*  BPTR to C string */
	
	if(namelen) (*namelen) = 0;
	
	if (task->tc_Node.ln_Type == NT_PROCESS && pr->pr_CLI != (BPTR)NULL)
	{
		struct CommandLineInterface *cli =
			(struct CommandLineInterface *)BADDR(pr->pr_CLI);
		
		if(cli && cli->cli_Module && cli->cli_CommandName)
		{
			STRPTR bn = (STRPTR) b2c(cli->cli_CommandName);
			
			if(*bn > 0)
			{
				if((name = StrNDup( &bn[1], *bn )))
				{
					if(namelen) (*namelen) = *bn;
				}
			}
		}
	}
	
	if( name == NULL )
	{
		UWORD len = strlen(task->tc_Node.ln_Name);
		
		if((name = StrNDup(task->tc_Node.ln_Name, len )))
		{
			if(namelen) (*namelen) = len;
		}
	}
	
//	DBG_STRING(name);
	
//	RETURN(name);
	return(name);
}
Ejemplo n.º 3
0
/*
** Replace the string in *pzDest with the string in zSrc
*/
static void ReplaceStr(char **pzDest, const char *zSrc){
  if( *pzDest!=0 ) HtmlFree(*pzDest);
  if( zSrc==0 ){
    *pzDest = 0;
  }else{
    *pzDest = StrNDup(zSrc, -1);
  }
}
Ejemplo n.º 4
0
static void
addServers( char **srv, int bType )
{
	char *name, *class2;
	const char *dtx, *cls;
	struct display *d;

	for (; *srv; srv++) {
		if ((cls = strchr( *srv, '_' ))) {
			if (!StrNDup( &name, *srv, cls - *srv ))
				return;
			if (!StrDup( &class2, cls )) {
				free( name );
				return;
			}
		} else {
			if (!StrDup( &name, *srv ))
				return;
			class2 = 0;
		}
		if ((d = FindDisplayByName( name ))) {
			if (d->class2)
				free( d->class2 );
			dtx = "existing";
		} else {
			if (!(d = NewDisplay( name ))) {
				free( name );
				if (class2)
					free( class2 );
				return;
			}
			dtx = "new";
		}
		d->stillThere = 1;
		d->class2 = class2;
		d->displayType = (*name == ':' ? dLocal : dForeign) | bType;
		if ((bType & d_lifetime) == dReserve) {
			if (d->status == notRunning)
				d->status = reserve;
		} else {
			if (d->status == reserve)
				d->status = notRunning;
		}
		Debug( "found %s %s%s display: %s %s\n", dtx,
		       ((d->displayType & d_location) == dLocal) ? "local" : "foreign",
		       ((d->displayType & d_lifetime) == dReserve) ? " reserve" : "",
		       d->name, d->class2 );
		free( name );
	}
}
Ejemplo n.º 5
0
/** extract filename between '`' and "'" 
 * Make v4.0 changed this: the first separator is now "'"
 */
static char* targetName(const char* line)
	{
	char* p;
	char* b=strchr(line,'`');
	if(b==NULL) b=strchr(line,'\'');//GNU make 4.0
      	char* e=( b==NULL ? NULL : strchr(b+1,'\'') );
      	if(b==NULL  || e==NULL || b>e)
      		{
      		fprintf(stderr,"Cannot get target name in \"%s\".\n",line);
      		exit(EXIT_FAILURE);
      		}
        p= StrNDup(b+1,(e-b)-1);
	if(p==NULL) OUT_OF_MEMORY;
	return p;
	}
Ejemplo n.º 6
0
static bool ParsePair(ParserT *parser, JsonPairT *pair) {
  TokenT *string = ParserMatch(parser, TOK_STRING);

  if (!string) {
    parser->errmsg = "string expected";
    return false;
  }

  if (!ParserMatch(parser, TOK_COLON)) {
    parser->errmsg = "':' expected";
    return false;
  }

  if (!ParseValue(parser, &pair->value))
    return false;

  pair->key = StrNDup(string->value + 1, string->size - 2);
  return true;
}
Ejemplo n.º 7
0
INLINE STRPTR StrDup( STRPTR string )
{
	return( StrNDup ( string, (ULONG) strlen( string ) + 1 ));
}
Ejemplo n.º 8
0
int
main( int argc, char **argv )
{
	int oldpid, oldumask, fd, noDaemonMode;
	char *pt, *errorLogFile, **opts;

	/* make sure at least world write access is disabled */
	if (((oldumask = umask( 022 )) & 002) == 002)
		(void)umask( oldumask );

	/* give /dev/null as stdin */
	if ((fd = open( "/dev/null", O_RDONLY )) > 0) {
		dup2( fd, 0 );
		close( fd );
	}
	if (fcntl( 1, F_GETFD ) < 0)
		dup2( 0, 1 );
	if (fcntl( 2, F_GETFD ) < 0)
		dup2( 0, 2 );

	if (argv[0][0] == '/') {
		if (!StrDup( &progpath, argv[0] ))
			Panic( "Out of memory" );
	} else
#ifdef __linux__
	{
		/* note that this will resolve symlinks ... */
		int len;
		char fullpath[PATH_MAX];
		if ((len = readlink( "/proc/self/exe", fullpath, sizeof(fullpath) )) < 0)
			Panic( "Invoke with full path specification or mount /proc" );
		if (!StrNDup( &progpath, fullpath, len ))
			Panic( "Out of memory" );
	}
#else
# if 0
		Panic( "Must be invoked with full path specification" );
# else
	{
		char directory[PATH_MAX+1];
		if (!getcwd( directory, sizeof(directory) ))
			Panic( "Can't find myself (getcwd failed)" );
		if (strchr( argv[0], '/' ))
			StrApp( &progpath, directory, "/", argv[0], (char *)0 );
		else {
			int len;
			char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1];

			if (!(path = getenv( "PATH" )))
				Panic( "Can't find myself (no PATH)" );
			len = strlen( argv[0] );
			name = nambuf + PATH_MAX - len;
			memcpy( name, argv[0], len + 1 );
			*--name = '/';
			do {
				if (!(pathe = strchr( path, ':' )))
					pathe = path + strlen( path );
				len = pathe - path;
				if (!len || (len == 1 && *path == '.')) {
					len = strlen( directory );
					path = directory;
				}
				thenam = name - len;
				if (thenam >= nambuf) {
					memcpy( thenam, path, len );
					if (!access( thenam, X_OK ))
						goto found;
				}
				path = pathe;
			} while (*path++ != '\0');
			Panic( "Can't find myself (not in PATH)" );
		  found:
			if (!StrDup( &progpath, thenam ))
				Panic( "Out of memory" );
		}
	}
# endif
#endif
	prog = strrchr( progpath, '/' ) + 1;

#if !defined(HAVE_SETPROCTITLE) && !defined(NOXDMTITLE)
	Title = argv[0];
	TitleLen = (argv[argc - 1] + strlen( argv[argc - 1] )) - Title;
#endif

	/*
	 * Parse command line options
	 */
	noDaemonMode = getppid();
	errorLogFile = 0;
	if (!(opts = Malloc( 2 * sizeof(char *) )))
		return 1;
	opts[0] = (char *)"";
	opts[1] = 0;
	while (*++argv) {
		if (**argv != '-')
			break;
		pt = *argv + 1;
		if (*pt == '-')
			pt++;
		if (!strcmp( pt, "help" ) || !strcmp( pt, "h" )) {
			printf( "Usage: %s [options] [tty]\n"
"  -daemon\t  - Daemonize even when started by init\n"
"  -nodaemon\t  - Don't daemonize even when started from command line\n"
"  -config <file>  - Use alternative master configuration file\n"
"  -xrm <res>\t  - Override frontend-specific resource\n"
"  -error <file>\t  - Use alternative log file\n"
"  -debug <num>\t  - Debug option bitfield:\n"
"\t\t\t0x1 - core log\n"
"\t\t\t0x2 - config reader log\n"
"\t\t\t0x4 - greeter log\n"
"\t\t\t0x8 - IPC log\n"
"\t\t\t0x10 - session sub-daemon post-fork delay\n"
"\t\t\t0x20 - config reader post-start delay\n"
"\t\t\t0x40 - greeter post-start delay\n"
"\t\t\t0x80 - don't use syslog\n"
"\t\t\t0x100 - core Xauth log\n"
"\t\t\t0x400 - valgrind config reader and greeter\n"
"\t\t\t0x800 - strace config reader and greeter\n"
			        , prog );
			exit( 0 );
		} else if (!strcmp( pt, "daemon" ))
			noDaemonMode = 0;
		else if (!strcmp( pt, "nodaemon" ))
			noDaemonMode = 1;
		else if (argv[1] && !strcmp( pt, "config" ))
			StrDup( opts, *++argv );
		else if (argv[1] && !strcmp( pt, "xrm" ))
			opts = addStrArr( opts, *++argv, -1 );
		else if (argv[1] && !strcmp( pt, "debug" ))
			sscanf( *++argv, "%i", &debugLevel );
		else if (argv[1] && (!strcmp( pt, "error" ) || !strcmp( pt, "logfile" )))
			errorLogFile = *++argv;
		else {
			fprintf( stderr, "\"%s\" is an unknown option or is missing a parameter\n", *argv );
			exit( 1 );
		}
	}

	/*
	 * Only allow root to run in non-debug mode to avoid problems
	 */
	if (!debugLevel && getuid()) {
		fprintf( stderr, "Only root wants to run %s\n", prog );
		exit( 1 );
	}

	InitErrorLog( errorLogFile );

	if (noDaemonMode != 1)
		BecomeDaemon();

	/*
	 * Step 1 - load configuration parameters
	 */
	if (!InitResources( opts ) || ScanConfigs( FALSE ) < 0)
		LogPanic( "Config reader failed. Aborting ...\n" );

	/* SUPPRESS 560 */
	if ((oldpid = StorePid())) {
		if (oldpid == -1)
			LogError( "Can't create/lock pid file %s\n", pidFile );
		else
			LogError( "Can't lock pid file %s, another xdm is running (pid %d)\n",
			          pidFile, oldpid );
		exit( 1 );
	}

#ifdef NEED_ENTROPY
	AddOtherEntropy();
#endif

	/*
	 * We used to clean up old authorization files here. As authDir is
	 * supposed to be /var/run/xauth or /tmp, we needn't to care for it.
	 */

#ifdef XDMCP
	init_session_id();
#else
	Debug( "not compiled for XDMCP\n" );
#endif
	if (pipe( signalFds ))
		LogPanic( "Unable to create signal notification pipe.\n" );
	RegisterInput( signalFds[0] );
	RegisterCloseOnFork( signalFds[0] );
	RegisterCloseOnFork( signalFds[1] );
	(void)Signal( SIGTERM, SigHandler );
	(void)Signal( SIGINT, SigHandler );
	(void)Signal( SIGHUP, SigHandler );
	(void)Signal( SIGCHLD, SigHandler );
	(void)Signal( SIGUSR1, SigHandler );

	/*
	 * Step 2 - run a sub-daemon for each entry
	 */
#ifdef XDMCP
	UpdateListenSockets();
#endif
	openCtrl( 0 );
	MainLoop();
	closeCtrl( 0 );
	if (sdRec.how) {
		commitBootOption();
		if (Fork() <= 0) {
			char *cmd = sdRec.how == SHUT_HALT ? cmdHalt : cmdReboot;
			execute( parseArgs( (char **)0, cmd ), (char **)0 );
			LogError( "Failed to execute shutdown command %\"s\n", cmd );
			exit( 1 );
		} else {
			sigset_t mask;
			sigemptyset( &mask );
			sigaddset( &mask, SIGCHLD );
			sigaddset( &mask, SIGHUP );
			sigsuspend( &mask );
		}
	}
	Debug( "nothing left to do, exiting\n" );
	return 0;
}
Ejemplo n.º 9
0
// ------------------------------------------------------------------------
bool S4::Interpreter::NextWord(S4::Lexeme *lexeme) {
    lexeme->kind = Lexeme::endOfInput;

    while (isspace(*programCounter)) {
        programCounter++;
    }

    if (*programCounter) {
        const char *startOfLexeme = programCounter;

        if (*programCounter == '\'' || *programCounter == '"' || *programCounter == '`') {
            char quote         = *(programCounter++);
            int  escapedQuotes = 0;
            int  escapedChars  = 0;
            while (*programCounter) {
                if (programCounter[0] == quote) {
                    if (programCounter[1] == quote) {
                        escapedQuotes   = 1;
                        programCounter += 2;
                        continue;
                    } else if (!programCounter[1] || isspace(programCounter[1])) {
                        // end of text
                        break;
                    }
                } else if (programCounter[0] == '\\') {
                    escapedChars = 1;
                }
                programCounter++;
            }
            lexeme->kind = Lexeme::text;
            // don't include the quotes in the copy
            //
            if (*programCounter == quote) {
                // advance past the closing quote before the copy
                programCounter++;
                lexeme->data.text = StrNDup(startOfLexeme + 1, (programCounter - 1) - (startOfLexeme + 1));
            } else {
                // unterminated string, sigh
                lexeme->data.text = StrNDup(startOfLexeme + 1, programCounter - (startOfLexeme + 1));
            }
            // TODO: combine quotes and backslash logic
            //
            if (escapedQuotes) {
                char *src = lexeme->data.text;
                while (*src && !(src[0] == quote && src[1] == quote)) {
                    src++;
                }
                char *dst = src;
                while (*src) {
                    if (src[0] == quote && src[1] == quote) {
                        src++;
                        *(dst++) = *(src++);
                    } else {
                        *(dst++) = *(src++);
                    }
                }
                *dst = 0;
            }
            if (escapedChars) {
                char *src = lexeme->data.text;
                while (*src && *src != '\\') {
                    src++;
                }
                char *dst = src;
                while (*src) {
                    if (*src != '\\') {
                        *(dst++) = *(src++);
                    } else {
                        switch (*(++src)) { // inspired by C strings
                        case 0:
                            // never escape null bytes (or quotes for that matter)
                            break;
                        case '0': // \0 is a null byte in the string
                            *(dst++) = 0;
                            src++;
                            break;
                        case 'n': // \n is a newline
                            *(dst++) = '\n';
                            src++;
                            break;
                        case 'r': // \r is a carriage return
                            *(dst++) = '\r';
                            src++;
                            break;
                        case 't': // \t is a tab
                            *(dst++) = '\t';
                            src++;
                            break;
                        default:
                            *(dst++) = *(src++);
                            break;
                        }
                    }
                }
                *dst = 0;
            }
            return lexeme;
        }

        if (isdigit(programCounter[0]) || ((programCounter[0] == '-' || programCounter[1] == '+') && isdigit(programCounter[1]))) {
            do {
                programCounter++;
            } while (isdigit(programCounter[0]));
            if (isspace(*programCounter) || !*programCounter) {
                lexeme->kind = Lexeme::integer;
                lexeme->data.integer = atoi(startOfLexeme);
                return lexeme;
            }
            if (programCounter[0] == '.' && isdigit(programCounter[1])) {
                do {
                    programCounter++;
                } while (isdigit(programCounter[0]));
                if (isspace(*programCounter) || !*programCounter) {
                    lexeme->kind = Lexeme::number;
                    lexeme->data.number = strtod(startOfLexeme, 0);
                    return lexeme;
                }
            }
        }

        while (*programCounter && !isspace(*programCounter)) {
            programCounter++;
        }
        lexeme->kind = Lexeme::symbol;
        lexeme->data.symbol = StrNDup(startOfLexeme, programCounter - startOfLexeme);
        return lexeme;
    }

    lexeme->kind = Lexeme::endOfInput;

    return false;
}
Ejemplo n.º 10
0
static LONG
PathWalk(Global_T *g, 
	 UBYTE *FullName,
	 LONG FullNameLen,
	 UBYTE *LinkPath,	/* Buf to get result into, IN/OUTPUT name of LINK */
	 ULONG BufLen,		/* length of buf above */
	 LONG *Res2)		/* OUTPUT */
{
    UBYTE *PComp; /* points to current path component */
    UBYTE *WorkPath = NULL;
    DCEntry *ParDir, *ActDir;
    NEntry *ActNEnt;
    ACEntry *ACE;
    LONG LastElement = 0; /* flag: if set, last element of directory is found */
    /* (init important !) */
    LONG Pos = 0; /* fn_ScanPath needs this as buffer */
    /* (init important !) */
    LONG Res = 1;

    D(DBF_ALWAYS, "\tPathWalk(\"%s\")", FullName);

    WorkPath = StrNDup(FullName, FullNameLen); /* we will modify WorkPath */
    if(!WorkPath)
    {
	*Res2 = ERROR_NO_FREE_STORE;
	Res = 0;
	
    }
    else
    {
	/* get (cached) root handle */
	ParDir = GetDirEntry(g, 
			     NULL, /* no name entry */
			     g->g_MntAttr.fileid,
			     &g->g_MntFh,
			     NULL, /* currently not used */
			     Res2);
	if(ParDir)
	{
	    if(FullNameLen)	/* Filename != "" */
	    {
		do
		{
		    PComp = fn_ScanPath(WorkPath, FullNameLen,
					&Pos, &LastElement);
		    ASSERT(PComp);

		    D(DBF_ALWAYS,"\tPComp = \"%s\"", PComp);
		    if(*PComp == '/') /* goto parent dir, not allowed in this 
					 version, must be unified path ! */
		    {
			    E(DBF_ALWAYS, "FIXME: *** parent dir reference not allowed !!");
			    Res = 0;
			    break;
		    }
		    ActNEnt = GetNameEntry(g, ParDir, PComp, &ACE, Res2);
		    if(!ActNEnt)
		    {
			Res = 0;
			break;
		    }

		    if((ActNEnt->ne_FType != NFDIR)
		       && (ActNEnt->ne_FType != NFLNK))
		    {
			*Res2 = ERROR_INVALID_COMPONENT_NAME;
			Res = 0;
			break;
		    }
		    if(ActNEnt->ne_FType == NFLNK)
		    {
			nfspath u_lpath;
		    
			ASSERT(ACE);
			ASSERT(LinkPath);
			u_lpath = nfs_ReadLink(g->g_NFSClnt,
					       &ACE->ace_NFSFh, Res2);
			if(u_lpath)
			{
			    D(DBF_ALWAYS,"\treadlink returned: %s", u_lpath);
#if 0
			    if(UseUnixLinks(g))
				;
#endif
			    if(fn_InsertLink(LinkPath,
					     BufLen,
					     g->g_VolumeName,
					     FullName,
					     PComp-WorkPath,
					     strlen(PComp),
					     u_lpath,
					     Res2) == NULL)
			    {
				if(*Res2 == ERROR_NO_FREE_STORE)
				    Res = -1;
				else
				    Res = 0;
			    }
			    else
				Res = 2;
			}
			else
			{
			    Res = 0;
			}
			break;
		    }
		    /* note: GetDirEntry will modify ActNEnt if necessary */
		    ActDir = GetDirEntry(g, 
					 ActNEnt,
					 DCE_ID_UNUSED,
					 &ACE->ace_NFSFh,
					 PComp,
					 Res2);
		    ParDir = ActDir;
		} while(!LastElement && ParDir);
	    }
	    else
	    {			/* filename: "" */
		LinkPath[0] = 0;
		Res = 1;
	    }
	}
	else
	    Res = 0;
	fn_Delete(&WorkPath);
    }
    return Res;
}
Ejemplo n.º 11
0
int StrDup(char **dst, const char *src)
{
    return StrNDup(dst, src, -1);
}
Ejemplo n.º 12
0
void            Load_Inputs_Src_List (void)
{
    int             i;
    char            w[256];
    t_input_src *   input_src = NULL;

    t_tfile *       tf;
    t_list *        lines;
    int             line_cnt;

    // Open and read file
    ConsolePrint (Msg_Get (MSG_Inputs_Src_Loading));
    tf = tfile_read (Inputs.FileName);
    if (tf == NULL)
        Quit_Msg (meka_strerror());
    ConsolePrint ("\n");

    // Parse each line
    line_cnt = 0;
    for (lines = tf->data_lines; lines; lines = lines->next)
    {
        char *line;

        line_cnt += 1;
        line = lines->elem;

        if (StrNull(line))
            continue;

        if (line[0] == '[' && line[strlen(line) - 1] == ']')
        {
            input_src = Inputs_Sources_Add (StrNDup (line + 1, strlen(line) - 2));
            // ConsolePrintf ("new source --> %s <--\n", CurSrc->Name);
            continue;
        }

        strlwr(line);
        if (!parse_getword(w, sizeof(w), &line, "=", ';', PARSE_FLAGS_NONE))
            continue;

        for (i = 0; Inputs_Src_List_KeyWords[i]; i++)
            if (strcmp(w, Inputs_Src_List_KeyWords[i]) == 0)
            {
                // FIXME: this is ugly
                if (input_src == NULL && strcmp (w, "joy_driver") != 0
                    && strcmp (w, "mouse_speed_x") != 0
                    && strcmp (w, "mouse_speed_y") != 0
                    && strcmp (w, "cabinet_mode")  != 0)
                {
                    tfile_free(tf);
                    Quit_Msg (Msg_Get (MSG_Inputs_Src_Missing), line_cnt);
                }

                parse_skip_spaces(&line);
                if (!parse_getword(w, sizeof(w), &line, "", ';', PARSE_FLAGS_NONE))
                {
                    tfile_free(tf);
                    Quit_Msg (Msg_Get (MSG_Inputs_Src_Equal), line_cnt);
                }

                switch (Load_Inputs_Src_Parse_Var(i, w, input_src))
                {
                case MEKA_ERR_SYNTAX:
                    tfile_free(tf);
                    Quit_Msg (Msg_Get (MSG_Inputs_Src_Syntax_Param), line_cnt);
                case MEKA_ERR_INCOHERENT :
                    tfile_free(tf);
                    Quit_Msg (Msg_Get (MSG_Inputs_Src_Inconsistency), line_cnt);
                    break;
                    // FIXME: EMPTY is not handled there
                }
                break;
            }
            if (!Inputs_Src_List_KeyWords [i])
            {
                tfile_free(tf);
                Quit_Msg (Msg_Get (MSG_Inputs_Src_Unrecognized), line_cnt, w);
            }
    }

    // Free file data
    tfile_free(tf);

    // Verify that we have enough inputs sources
    if (Inputs.Sources_Max == 0)
        Quit_Msg (Msg_Get (MSG_Inputs_Src_Not_Enough));
}
Ejemplo n.º 13
0
static void manage(struct sockaddr *from, int fromlen, int length, int fd)
{
    CARD32 sessionID;
    CARD16 displayNumber;
    ARRAY8 displayClass;
    int expectlen;
    struct protoDisplay *pdpy;
    struct display *d;
    char *name = NULL;
    char *class2 = NULL;
    XdmcpNetaddr from_save;
    ARRAY8 clientAddress, clientPort;
    CARD16 connectionType;

    Debug("<manage> %d\n", length);
    displayClass.data = 0;
    displayClass.length = 0;
    if(XdmcpReadCARD32(&buffer, &sessionID) && XdmcpReadCARD16(&buffer, &displayNumber) && XdmcpReadARRAY8(&buffer, &displayClass))
    {
        expectlen = 4 +                      /* session ID */
                    2 +                      /* displayNumber */
                    2 + displayClass.length; /* displayClass */
        if(expectlen != length)
        {
            Debug("<manage> length error got %d expect %d\n", length, expectlen);
            goto abort;
        }
        pdpy = FindProtoDisplay((XdmcpNetaddr)from, fromlen, displayNumber);
        Debug("<manage> session ID %ld, pdpy %p\n", (long)sessionID, pdpy);
        if(!pdpy || pdpy->sessionID != sessionID)
        {
            /*
             * We may have already started a session for this display
             * but it hasn't seen the response in the form of an
             * XOpenDisplay() yet. So check if it is in the list of active
             * displays, and if so check that the session id's match.
             * If all this is true, then we have a duplicate request that
             * can be ignored.
             */
            if(!pdpy && (d = FindDisplayByAddress((XdmcpNetaddr)from, fromlen, displayNumber)) && d->sessionID == sessionID)
            {
                Debug("manage: got duplicate pkt, ignoring\n");
                goto abort;
            }
            Debug("session ID %ld refused\n", (long)sessionID);
            if(pdpy)
                Debug("existing session ID %ld\n", (long)pdpy->sessionID);
            send_refuse(from, fromlen, sessionID, fd);
        }
        else
        {
            name = NetworkAddressToName(pdpy->connectionType, &pdpy->connectionAddress, from, pdpy->displayNumber);
            if(!name)
            {
                Debug("could not compute display name\n");
                send_failed(from, fromlen, "(no name)", sessionID, "out of memory", fd);
                goto abort;
            }
            Debug("computed display name: %s\n", name);
            if((d = FindDisplayByName(name)))
            {
                Debug("terminating active session for %s\n", d->name);
                StopDisplay(d);
            }
            if(displayClass.length)
            {
                if(!StrNDup(&class2, (char *)displayClass.data, displayClass.length))
                {
                    send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                    goto abort;
                }
            }
            if(!(from_save = (XdmcpNetaddr)Malloc(fromlen)))
            {
                send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                goto abort;
            }
            memmove(from_save, from, fromlen);
            if(!(d = NewDisplay(name)))
            {
                free((char *)from_save);
                send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                goto abort;
            }
            d->class2 = class2;
            class2 = 0;
            d->displayType = dForeign | dTransient | dFromXDMCP;
            d->sessionID = pdpy->sessionID;
            d->from.data = (unsigned char *)from_save;
            d->from.length = fromlen;
            d->displayNumber = pdpy->displayNumber;
            ClientAddress(from, &clientAddress, &clientPort, &connectionType);
            d->useChooser = 0;
            d->xdmcpFd = fd;
            if(IsIndirectClient(&clientAddress, connectionType))
            {
                Debug("IsIndirectClient\n");
                ForgetIndirectClient(&clientAddress, connectionType);
                if(UseChooser(&clientAddress, connectionType))
                {
                    d->useChooser = 1;
                    Debug("use chooser for %s\n", d->name);
                }
            }
            d->clientAddr = clientAddress;
            d->connectionType = connectionType;
            d->remoteHost = NetworkAddressToHostname(pdpy->connectionType, &pdpy->connectionAddress);

            XdmcpDisposeARRAY8(&clientPort);
            if(pdpy->fileAuthorization)
            {
                d->authorizations = (Xauth **)Malloc(sizeof(Xauth *));
                if(!d->authorizations)
                {
                    free((char *)from_save);
                    free((char *)d);
                    send_failed(from, fromlen, name, sessionID, "out of memory", fd);
                    goto abort;
                }
                d->authorizations[0] = pdpy->fileAuthorization;
                d->authNum = 1;
                pdpy->fileAuthorization = 0;
            }
            DisposeProtoDisplay(pdpy);
            Debug("starting display %s,%s\n", d->name, d->class2);
            if(LoadDisplayResources(d) < 0)
            {
                LogError(
                    "Unable to read configuration for display %s; "
                    "stopping it.\n",
                    d->name);
                StopDisplay(d);
            }
            else
                StartDisplay(d);
            CloseGetter();
        }
    }
abort:
    XdmcpDisposeARRAY8(&displayClass);
    if(name)
        free((char *)name);
    if(class2)
        free((char *)class2);
}