Example #1
0
int
var_string(
	char	*in,
	char	*out,
	int	outsize,
	LOL	*lol )
{
	char 	*out0 = out;
	char	*oute = out + outsize - 1;

	while( *in )
	{
	    char	*lastword;
	    int		dollar = 0;

	    /* Copy white space */

	    while( isspace( *in ) )
	    {
		if( out >= oute )
		    return -1;

		*out++ = *in++;
	    }

	    lastword = out;

	    /* Copy non-white space, watching for variables */

	    while( *in && !isspace( *in ) )
	    {
	        if( out >= oute )
		    return -1;

		if( in[0] == '$' && in[1] == '(' )
		    dollar++;
                #ifdef OPT_AT_FILES
                else if ( in[0] == '@' && in[1] == '(' )
                {
                    int depth = 1;
                    char *ine = in + 2;
                    char *split = 0;
                    
                    /* Scan the content of the response file @() section. */
                    
                    while( *ine && depth > 0 )
                    {
                        switch( *ine )
                        {
                        case '(':
                            ++depth;
                            break;
                        case ')':
                            --depth;
                            break;
                        case ':':
                            if( depth == 1 && ine[1] == 'E' && ine[2] == '=' )
                            {
                                split = ine;
                            }
                           break;
                        }
                        ++ine;
                    }
                    
                    if (!split)
                    {
                        printf( "no file specified!\n" );
                        exit( EXITBAD );
                    }
                    
                    if ( depth == 0 )
                    {
                        string file_name_v;
                        int file_name_l = 0;
                        const char * file_name_s = 0;
                        
                        /* expand the temporary file name var inline */
                        #if 0
                        string_copy(&file_name_v,"$(");
                        string_append_range(&file_name_v,in+2,split);
                        string_push_back(&file_name_v,')');
                        #else
                        string_new(&file_name_v);
                        string_append_range(&file_name_v,in+2,split);
                        #endif
                        file_name_l = var_string(file_name_v.value,out,oute-out+1,lol);
                        string_free(&file_name_v);
                        if ( file_name_l < 0 ) return -1;
                        file_name_s = out;
                        
                        /* for stdout/stderr we will create a temp file and generate
                           a command that outputs the content as needed. */
                        if ( strcmp( "STDOUT", out ) == 0 || strcmp( "STDERR", out ) == 0 )
                        {
                            int err_redir = strcmp( "STDERR", out ) == 0;
                            out[0] = '\0';
                            file_name_s = path_tmpfile();
                            file_name_l = strlen(file_name_s);
                            #ifdef OS_NT
                            if ( (out+7+file_name_l+(err_redir?5:0)) >= oute ) return -1;
                            sprintf( out,"type \"%s\"%s",
                                file_name_s,
                                err_redir ? " 1>&2" : "" );
                            #else
                            if ( (out+6+file_name_l+(err_redir?5:0)) >= oute ) return -1;
                            sprintf( out,"cat \"%s\"%s",
                                file_name_s,
                                err_redir ? " 1>&2" : "" );
                            #endif
                            /* we also make sure that the temp files created by this
                               get nuked eventually. */
                            file_remove_atexit( file_name_s );
                        }
                        
                        /* expand the file value into the file reference */
                        if ( !globs.noexec )
                            var_string_to_file( split+3, ine-split-4, file_name_s, lol );
                        
                        /* continue on with the expansion */
                        out += strlen(out);
                    }
                    
                    /* and continue with the parsing just past the @() reference */
                    in = ine;
                }
                #endif

		*out++ = *in++;
	    }

        /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
        if (out >= oute)
            return -1;
        /* Don't increment, intentionally. */
        *out= '\0';
           
	    /* If a variable encountered, expand it and and embed the */
	    /* space-separated members of the list in the output. */

	    if( dollar )
	    {
		LIST	*l;

		l = var_expand( L0, lastword, out, lol, 0 );

		out = lastword;

		while ( l )
		{
		    int so = strlen( l->string );

		    if( out + so >= oute )
			return -1;

		    strcpy( out, l->string );
		    out += so;
		    l = list_next( l );
		    if ( l ) *out++ = ' ';
		}

		list_free( l );
	    }
	}

	if( out >= oute )
	    return -1;

	*out++ = '\0';

	return out - out0;
}
Example #2
0
int var_string( const char * in, char * out, int outsize, LOL * lol )
{
    char * out0 = out;
    char * oute = out + outsize - 1;

    while ( *in )
    {
        char * lastword;
        int    dollar = 0;

        /* Copy white space. */
        while ( isspace( *in ) )
        {
            if ( out >= oute )
                return -1;
            *out++ = *in++;
        }

        lastword = out;

        /* Copy non-white space, watching for variables. */
        while ( *in && !isspace( *in ) )
        {
            if ( out >= oute )
                return -1;

            if ( ( in[ 0 ] == '$' ) && ( in[ 1 ] == '(' ) )
            {
                ++dollar;
                *out++ = *in++;
            }
            #ifdef OPT_AT_FILES
            else if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) )
            {
                int depth = 1;
                const char * ine = in + 2;
                const char * split = 0;

                /* Scan the content of the response file @() section. */
                while ( *ine && ( depth > 0 ) )
                {
                    switch ( *ine )
                    {
                    case '(': ++depth; break;
                    case ')': --depth; break;
                    case ':':
                        if ( ( depth == 1 ) && ( ine[ 1 ] == 'E' ) && ( ine[ 2 ] == '=' ) )
                            split = ine;
                        break;
                    }
                    ++ine;
                }

                if ( !split )
                {
                    /*  the @() reference doesn't match the @(foo:E=bar) format.
                        hence we leave it alone by copying directly to output. */
                    int l = 0;
                    if ( out + 2 >= oute ) return -1;
                    *( out++ ) = '@';
                    *( out++ ) = '(';
                    l = var_string( in + 2, out, oute - out, lol );
                    if ( l < 0 ) return -1;
                    out += l;
                    if ( out + 1 >= oute ) return -1;
                    *( out++ ) = ')';
                }
                else if ( depth == 0 )
                {
                    string file_name_v;
                    OBJECT * file_name = 0;
                    int file_name_l = 0;
                    const char * file_name_s = 0;

                    /* Expand the temporary file name var inline. */
                    #if 0
                    string_copy( &file_name_v, "$(" );
                    string_append_range( &file_name_v, in + 2, split );
                    string_push_back( &file_name_v, ')' );
                    #else
                    string_new( &file_name_v );
                    string_append_range( &file_name_v, in + 2, split );
                    #endif
                    file_name_l = var_string( file_name_v.value, out, oute - out + 1, lol );
                    string_free( &file_name_v );
                    if ( file_name_l < 0 ) return -1;
                    file_name_s = out;

                    /* For stdout/stderr we will create a temp file and generate
                     * a command that outputs the content as needed.
                     */
                    if ( ( strcmp( "STDOUT", out ) == 0 ) ||
                        ( strcmp( "STDERR", out ) == 0 ) )
                    {
                        int err_redir = strcmp( "STDERR", out ) == 0;
                        out[ 0 ] = '\0';

                        file_name = path_tmpfile();
                        file_name_s = object_str(file_name);
                        file_name_l = strlen(file_name_s);
                        #ifdef OS_NT
                        if ( ( out + 7 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute )
                            return -1;
                        sprintf( out,"type \"%s\"%s", file_name_s,
                            err_redir ? " 1>&2" : "" );
                        #else
                        if ( ( out + 6 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute )
                            return -1;
                        sprintf( out,"cat \"%s\"%s", file_name_s,
                            err_redir ? " 1>&2" : "" );
                        #endif
                        /* We also make sure that the temp files created by this
                         * get nuked eventually.
                         */
                        file_remove_atexit( file_name );
                    }

                    /* Expand the file value into the file reference. */
                    var_string_to_file( split + 3, ine - split - 4, file_name_s,
                        lol );

                    if ( file_name )
                    {
                        object_free( file_name );
                    }

                    /* Continue on with the expansion. */
                    out += strlen( out );
                }

                /* And continue with the parsing just past the @() reference. */
                in = ine;
            }
            #endif
            else
            {
                *out++ = *in++;
            }
        }

        /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */
        if ( out >= oute )
            return -1;
        /* Do not increment, intentionally. */
        *out = '\0';

        /* If a variable encountered, expand it and and embed the
         * space-separated members of the list in the output.
         */
        if ( dollar )
        {
            LIST * l = var_expand( L0, lastword, out, lol, 0 );
            LIST * saved = l;

            out = lastword;

            while ( l )
            {
                int so = strlen( object_str( l->value ) );

                if ( out + so >= oute )
                    return -1;

                strcpy( out, object_str( l->value ) );
                out += so;
                l = list_next( l );
                if ( l ) *out++ = ' ';
            }

            list_free( saved );
        }
    }

    if ( out >= oute )
        return -1;

    *out++ = '\0';

    return out - out0;
}