Example #1
0
uint16 _api_DosNetServerGetInfo(PCONN_HND phnd, io_struct * ps,
				uint16 sLevel,
				RCVBUF pbBuffer,
				RCVBUFLEN cbBuffer, uint16 *pcTotalAvail)
{
	SERVER_INFO_1 sv1;

	DEBUG(10,("DosNetServerGetInfo: %d buf %d\n",
				sLevel, cbBuffer));
	StrnCpy(sv1.sv1_name, local_machine, 16);
	strupper(sv1.sv1_name);
	sv1.sv1_version_major = 4;
	sv1.sv1_version_minor = 1;
	sv1.sv1_type = SV_TYPE_NT;

	sv1.sv1_comment_or_master_browser = string_truncate(lp_serverstring(),
					MAX_SERVER_STRING_LENGTH);

	switch (sLevel)
	{
		case 1:
		{
			if (!io_SERVER_INFO_1("sv1", ps, 0, &sv1,
						PARSE_SCALARS))
				return NERR_BufTooSmall;

			if (!io_SERVER_INFO_1("sv1", ps, 0, &sv1,
						PARSE_OFFSETS))
				return NERR_BufTooSmall;
			return ERRsuccess;
		}
	}
	return ERRunknownlevel;
}
Example #2
0
void
file_dirscan( 
	char *dir,
	scanback func,
	void	*closure )
{
    PATHNAME f;
    string filespec[1];
    long handle;
    int ret;
    struct _find_t finfo[1];

    /* First enter directory itself */

    memset( (char *)&f, '\0', sizeof( f ) );

    f.f_dir.ptr = dir;
    f.f_dir.len = strlen(dir);

    dir = *dir ? dir : ".";

    /* Special case \ or d:\ : enter it */
    string_copy( filespec, dir );

    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '\\' )
 	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
    else if( f.f_dir.len == 3 && f.f_dir.ptr[1] == ':' )
 	    (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );
    else
        string_push_back( filespec, '/' );

    string_push_back( filespec, '*' );

    /* Now enter contents of directory */

    if( DEBUG_BINDSCAN )
        printf( "scan directory %s\n", filespec->value );

    /* Time info in dos find_t is not very useful.  It consists */
    /* of a separate date and time, and putting them together is */
    /* not easy.  So we leave that to a later stat() call. */

    if( !_dos_findfirst( filespec->value, _A_NORMAL|_A_RDONLY|_A_SUBDIR, finfo ) )
    {
        string filename[1];
        string_new( filename );
        do
        {
            
            f.f_base.ptr = finfo->name;
            f.f_base.len = strlen( finfo->name );

            string_truncate( filename, 0 );
            path_build( &f, filename, 0 );
            (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
        }
        while( !_dos_findnext( finfo ) );
        string_free( filename );
    }
}
void announce_remote(time_t t)
{
    char *s;
    const char *ptr;
    static time_t last_time = 0;
    pstring s2;
    struct in_addr addr;
    char *comment;
    int stype = lp_default_server_announce();

    if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
        return;

    last_time = t;

    s = lp_remote_announce();
    if (!*s)
        return;

    comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);

    for (ptr=s; next_token(&ptr,s2,NULL,sizeof(s2)); ) {
        /* The entries are of the form a.b.c.d/WORKGROUP with
        		WORKGROUP being optional */
        const char *wgroup;
        char *pwgroup;
        int i;

        pwgroup = strchr_m(s2,'/');
        if (pwgroup)
            *pwgroup++ = 0;
        if (!pwgroup || !*pwgroup)
            wgroup = lp_workgroup();
        else
            wgroup = pwgroup;

        addr = *interpret_addr2(s2);

        /* Announce all our names including aliases */
        /* Give the ip address as the address of our first
        		broadcast subnet. */

        for(i=0; my_netbios_names(i); i++) {
            const char *name = my_netbios_names(i);

            DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
                     name, inet_ntoa(addr) ));

            send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
                              name,                      /* From nbt name. */
                              wgroup, 0x1d,              /* To nbt name. */
                              addr,                      /* To ip. */
                              REMOTE_ANNOUNCE_INTERVAL,  /* Time until next announce. */
                              name,                      /* Name to announce. */
                              stype,                     /* Type field. */
                              comment);
        }
    }
}
Example #4
0
/* EN: Enter Newline */
void cmd_en (int argc, char *argv[])
{
	pad_t  *pad = e->cpad;
	int     xpos;
	int     ypos;
	line_t *cline;
	line_t *newline;
	char   *extratext;
	int    intab;

	if (!(e->cpad->flags & FILE_WRITE))
	{
		output_message_c ("en", "Pad is read-only.");
		return;
	}

	ypos = pad->curs_y + pad->offset_y;

	if (ypos > pad->line_count)
		pad_grow (pad, ypos);

	LINE_insert (pad, ypos, "");
	cline = LINE_get_line_at (pad, ypos);

	if (cline->str != NULL)
	{
		xpos = get_string_pos (pad->curs_x + pad->offset_x, cline->str->data, &intab);

		if ((size_t)xpos < strlen (cline->str->data))
		{
			/* We're 'inside' the string. Get the text on the
			 * right, and truncate the current string. Then put
			 * the 'extra' text on the line we've inserted or
			 * allocated.
			 */

			extratext = cline->str->data + xpos;
			newline = LINE_get_line_at (pad, ypos + 1);
			newline->str = string_alloc ("%s", extratext);
			string_truncate (cline->str, xpos);
		}
	}

	pad->curs_x   = 1;
	pad->offset_x = 0;
	if (pad->curs_y == pad->height)
	{
		pad->offset_y++;
	}
	else
	{
		pad->curs_y++;
	}

	if (e->occupied_window == COMMAND_WINDOW)
		e->occupied_window = COMMAND_WINDOW_EXECUTE;
	else
		pad_modified (pad);
}
Example #5
0
int file_collect_dir_content_( file_info_t * const d )
{
    LIST * files = L0;
    PATHNAME f;
    int n;
    STRUCT_DIRENT ** namelist;
    STRUCT_DIRENT * dirent;
    string path[ 1 ];
    char const * dirstr;

    assert( d );
    assert( d->is_dir );
    assert( list_empty( d->files ) );

    dirstr = object_str( d->name );

    memset( (char *)&f, '\0', sizeof( f ) );
    f.f_dir.ptr = dirstr;
    f.f_dir.len = strlen( dirstr );

    if ( !*dirstr ) dirstr = ".";

    if ( -1 == ( n = scandir( dirstr, &namelist, NULL, alphasort ) ) )
        return -1;

    string_new( path );
    while ( n-- )
    {
        OBJECT * name;
        dirent = namelist[ n ];
        f.f_base.ptr = dirent->d_name
        #ifdef old_sinix
            - 2  /* Broken structure definition on sinix. */
        #endif
            ;
        f.f_base.len = strlen( f.f_base.ptr );

        string_truncate( path, 0 );
        path_build( &f, path );
        name = object_new( path->value );
        /* Immediately stat the file to preserve invariants. */
        if ( file_query( name ) )
            files = list_push_back( files, name );
        else
            object_free( name );
        free( dirent );
    }
    string_free( path );

    free( namelist );

    d->files = files;
    return 0;
}
Example #6
0
void
file_dirscan(
    char *dir,
    scanback func,
    void *closure )
{
    PATHNAME f;
    DIR *d;
    STRUCT_DIRENT *dirent;
    string filename[1];

    /* First enter directory itself */

    memset( (char *)&f, '\0', sizeof( f ) );

    f.f_dir.ptr = dir;
    f.f_dir.len = strlen(dir);

    dir = *dir ? dir : ".";

    /* Special case / : enter it */

    if( f.f_dir.len == 1 && f.f_dir.ptr[0] == '/' )
        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );

    /* Now enter contents of directory */

    if( !( d = opendir( dir ) ) )
        return;

    if( DEBUG_BINDSCAN )
        printf( "scan directory %s\n", dir );

    string_new( filename );
    while( dirent = readdir( d ) )
    {
# ifdef old_sinix
        /* Broken structure definition on sinix. */
        f.f_base.ptr = dirent->d_name - 2;
# else
        f.f_base.ptr = dirent->d_name;
# endif
        f.f_base.len = strlen( f.f_base.ptr );

        string_truncate( filename, 0 );
        path_build( &f, filename, 0 );

        (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
    }
    string_free( filename );

    closedir( d );
}
Example #7
0
static void StrAppend(char *buffer, char *fmt, int len, char *str)
{
   char OneItem[100];
   char msg[100];
   sprintf(OneItem,fmt, str);
   string_truncate(OneItem, msg, len, 100);
   if((int)strlen(OneItem) > len) {
     css_warning("%s truncated to (%s) to fit format requirements...\n", OneItem, msg);
   }
   strncat(buffer, msg, len);
   strcat(buffer, " ");
}
Example #8
0
void mangle_map(pstring OutName, BOOL need83, BOOL cache83, int snum)
{
	/* name mangling can be disabled for speed, in which case
	   we just truncate the string */
	if (!lp_manglednames(snum)) {
		if (need83) {
			string_truncate(OutName, 12);
		}
		return;
	}

	/* invoke the inane "mangled map" code */
	mangle_map_filename(OutName, snum);
	mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(snum));
}
Example #9
0
void mangle_map(pstring OutName, BOOL need83, BOOL cache83,
		const struct share_params *p)
{
	/* name mangling can be disabled for speed, in which case
	   we just truncate the string */
	if (!lp_manglednames(p)) {
		if (need83) {
			string_truncate(OutName, 12);
		}
		return;
	}

	/* invoke the inane "mangled map" code */
	mangle_map_filename(OutName, p);
	mangle_fns->name_map(OutName, need83, cache83, lp_defaultcase(p->service), p);
}
Example #10
0
VOID setting_write(CHAR *filename, CHAR *key, CHAR *value)
{
	STRING *str;
	CHAR *tmpbuf;
	CHAR *pkey;
	CHAR *p;

	os_lock_lock(settinglock);	


	tmpbuf = setting_load_file(filename);
	str = string_new(tmpbuf);

	pkey = setting_find_key(tmpbuf, key, NULL);

	if(pkey != NULL)
	{
		string_truncate(str, pkey - tmpbuf);
		str = string_append(str, key);
		str = string_append(str, "=");
		str = string_append(str, value);
		str = string_append(str, "\r\n");

		p = strstr(pkey, "\n");
		if(p)
			str = string_append(str, p + 2);
		else
			str = string_append(str, "\n\n");
	}
	else
	{
		str = string_append(str, key);
		str = string_append(str, "=");
		str = string_append(str, value);
		str = string_append(str, "\r\n");
	}

	os_free(tmpbuf);

	setting_save_file(filename, str->str);
	string_free(str);
	
	os_lock_unlock(settinglock);
}
Example #11
0
buffer_t *buffer_load (char *file_name)
{
	char *full_path;
	char line[512];
	FILE *f;
	buffer_t *buf;

	/* use line first to store the full path name */
	full_path = line;

	if (*file_name != '/')
		sprintf (full_path, "%s/.gronda/buffer/%s", 
		                    getenv ("HOME"), file_name);
	else
		strcpy (full_path, file_name);

	f = fopen (full_path, "r");
	if (f == NULL)
	{
		output_message ("Error loading buffer %s", file_name);
		return NULL;
	}

	buf = buffer_create (file_name);

	if (buf == NULL)
	{
		output_message ("Error creating buffer");
		return NULL;
	}

	if (*(buf->str->data))
		string_truncate (buf->str, 0);

	/* line is now used to store data from the file stream */ 
	while (fgets (line, 512, f))
		string_append (buf->str, line);

	fclose (f);

	return buf;
}
Example #12
0
INT setting_get_key_value(CHAR *valueptr, STRING *str)
{
	CHAR *p, *p1;
	INT valuelen;

	p = valueptr;

	if(!p || !str) return 0;

	p1 = strchr(p, '\n');

	if(!p1)
		valuelen = strlen(p);
	else
		valuelen = p1 - p;

	//str = string_assign(str, p);
	//string_truncate(str, valuelen);
	string_truncate(str, 0);
	string_nappend(str, p, valuelen);
	return valuelen;
}
Example #13
0
STRING *string_nappend(STRING *str, CHAR *newstr, INT len)
{
	CHAR *p;
	INT newlen;
	
	if(!newstr) return NULL;

	if(!str) 
	{
		str = string_new(newstr);
		str = string_truncate(str, len);
		return str;
	}

	if (len + str->len >= str->allocated_len )
	{
		newlen = (len + str->len) * 3 / 2 + 1;
		p = os_new(CHAR, newlen);
		str->allocated_len = newlen;
		strcpy(p, str->str);
	}
	else
	{ 
		p = str->str;
	}
	//strncpy(p + str->len, newstr, len);
	strncat(p, newstr, len);

	if(p != str->str)
	{
		os_free(str->str);
		str->str = p;
	}
	str->len += len;

	str->str[str->len] = 0;
	return str;
}
Example #14
0
LIST * regex_transform( FRAME * frame, int flags )
{
    LIST * const l = lol_get( frame->args, 0 );
    LIST * const pattern = lol_get( frame->args, 1 );
    LIST * const indices_list = lol_get( frame->args, 2 );
    int * indices = 0;
    int size;
    LIST * result = L0;

    if ( !list_empty( indices_list ) )
    {
        int * p;
        LISTITER iter = list_begin( indices_list );
        LISTITER const end = list_end( indices_list );
        size = list_length( indices_list );
        indices = (int *)BJAM_MALLOC( size * sizeof( int ) );
        for ( p = indices; iter != end; iter = list_next( iter ) )
            *p++ = atoi( object_str( list_item( iter ) ) );
    }
    else
    {
        size = 1;
        indices = (int *)BJAM_MALLOC( sizeof( int ) );
        *indices = 1;
    }

    {
        /* Result is cached and intentionally never freed */
        regexp * const re = regex_compile( list_front( pattern ) );

        LISTITER iter = list_begin( l );
        LISTITER const end = list_end( l );

        string buf[ 1 ];
        string_new( buf );

        for ( ; iter != end; iter = list_next( iter ) )
        {
            if ( regexec( re, object_str( list_item( iter ) ) ) )
            {
                int i = 0;
                for ( ; i < size; ++i )
                {
                    int const index = indices[ i ];
                    /* Skip empty submatches. Not sure it is right in all cases,
                     * but surely is right for the case for which this routine
                     * is optimized -- header scanning.
                     */
                    if ( re->startp[ index ] != re->endp[ index ] )
                    {
                        string_append_range( buf, re->startp[ index ],
                            re->endp[ index ] );
                        result = list_push_back( result, object_new( buf->value
                            ) );
                        string_truncate( buf, 0 );
                    }
                }
            }
        }
        string_free( buf );
    }

    BJAM_FREE( indices );
    return result;
}
Example #15
0
/*
rule transform ( list * : pattern : indices * )
{
    indices ?= 1 ;
    local result ;
    for local e in $(list)
    {
        local m = [ MATCH $(pattern) : $(e) ] ;
        if $(m)
        {
            result += $(m[$(indices)]) ;
        }        
    }
    return $(result) ;
}
*/
LIST *regex_transform( FRAME *frame, int flags )
{
    LIST* l = lol_get( frame->args, 0 );    
    LIST* pattern = lol_get( frame->args, 1 );    
    LIST* indices_list = lol_get(frame->args, 2);
    int* indices = 0;
    int size;
    int* p;
    LIST* result = 0;

    string buf[1];
    string_new(buf);

    if (indices_list)
    {
        size = list_length(indices_list);
        indices = (int*)BJAM_MALLOC(size*sizeof(int));
        for(p = indices; indices_list; indices_list = indices_list->next)
        {
            *p++ = atoi(object_str(indices_list->value));
        }        
    }
    else 
    {
        size = 1;
        indices = (int*)BJAM_MALLOC(sizeof(int));
        *indices = 1;
    }

    {
        /* Result is cached and intentionally never freed */
        regexp *re = regex_compile( pattern->value );

        for(; l; l = l->next)
        {
            if( regexec( re, object_str( l->value ) ) )
            {
                int i = 0;
                for(; i < size; ++i)
                {
                    int index = indices[i];
                    /* Skip empty submatches. Not sure it's right in all cases,
                       but surely is right for the case for which this routine
                       is optimized -- header scanning.
                    */
                    if (re->startp[index] != re->endp[index])
                    {
                        string_append_range( buf, re->startp[index], re->endp[index] );
                        result = list_new( result, object_new( buf->value ) ); 
                        string_truncate( buf, 0 );
                    }
                }
            }
        }
        string_free( buf );
    }

    BJAM_FREE(indices);
    
    return result;
}
Example #16
0
void string_pop_back( string* self )
{
    string_truncate( self, self->size - 1 );
}
Example #17
0
static void canonicWindowsPath( char const * const path, int const path_length,
    string * const out )
{
    char const * last_element;
    unsigned long saved_size;
    char const * p;

    /* This is only called via path_key(), which initializes the cache. */
    assert( path_key_cache );

    if ( !path_length )
        return;

    if ( path_length == 1 && path[ 0 ] == '\\' )
    {
        string_push_back( out, '\\' );
        return;
    }

    if ( path[ 1 ] == ':' &&
        ( path_length == 2 ||
        ( path_length == 3 && path[ 2 ] == '\\' ) ) )
    {
        string_push_back( out, toupper( path[ 0 ] ) );
        string_push_back( out, ':' );
        string_push_back( out, '\\' );
        return;
    }

    /* Find last '\\'. */
    for ( p = path + path_length - 1; p >= path && *p != '\\'; --p );
    last_element = p + 1;

    /* Special case '\' && 'D:\' - include trailing '\'. */
    if ( p == path ||
        p == path + 2 && path[ 1 ] == ':' )
        ++p;

    if ( p >= path )
    {
        char const * const dir = path;
        int const dir_length = p - path;
        OBJECT * const dir_obj = object_new_range( dir, dir_length );
        int found;
        path_key_entry * const result = (path_key_entry *)hash_insert(
            path_key_cache, dir_obj, &found );
        if ( !found )
        {
            result->path = dir_obj;
            canonicWindowsPath( dir, dir_length, out );
            result->key = object_new( out->value );
        }
        else
        {
            object_free( dir_obj );
            string_append( out, object_str( result->key ) );
        }
    }

    if ( out->size && out->value[ out->size - 1 ] != '\\' )
        string_push_back( out, '\\' );

    saved_size = out->size;
    string_append_range( out, last_element, path + path_length );

    {
        char const * const n = last_element;
        int const n_length = path + path_length - n;
        if ( !( n_length == 1 && n[ 0 ] == '.' )
            && !( n_length == 2 && n[ 0 ] == '.' && n[ 1 ] == '.' ) )
        {
            WIN32_FIND_DATA fd;
            HANDLE const hf = FindFirstFileA( out->value, &fd );
            if ( hf != INVALID_HANDLE_VALUE )
            {
                string_truncate( out, saved_size );
                string_append( out, fd.cFileName );
                FindClose( hf );
            }
        }
    }
}
Example #18
0
void path_build( PATHNAME * f, string * file, int binding )
{
    struct dirinf root;
    struct dirinf dir;
    int g;

    file_build1( f, file );

    /* Get info on root and dir for combining. */
    dir_flags( f->f_root.ptr, f->f_root.len, &root );
    dir_flags( f->f_dir.ptr, f->f_dir.len, &dir );

    /* Combine. */
    switch ( g = grid[ root.flags ][ dir.flags ] )
    {
    case G_DIR:
        /* take dir */
        string_append_range( file, f->f_dir.ptr, f->f_dir.ptr + f->f_dir.len  );
        break;

    case G_ROOT:
        /* take root */
        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );
        break;

    case G_VAD:
        /* root's dev + abs directory */
        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );
        string_append_range( file, dir.dir.ptr, dir.dir.ptr + dir.dir.len  );
        break;

    case G_DRD:
    case G_DDD:
        /* root's dev:[dir] + rel directory */
        string_append_range( file, f->f_root.ptr, f->f_root.ptr + f->f_root.len  );

        /* sanity checks: root ends with ] */

        if ( file->value[file->size - 1] == ']' )
            string_pop_back( file );

        /* Add . if separating two -'s */

        if ( g == G_DDD )
            string_push_back( file, '.' );

        /* skip [ of dir */
        string_append_range( file, dir.dir.ptr + 1, dir.dir.ptr + 1 + dir.dir.len - 1  );
        break;

    case G_VRD:
        /* root's dev + rel directory made abs */
        string_append_range( file, root.dev.ptr, root.dev.ptr + root.dev.len  );
        string_push_back( file, '[' );
        /* skip [. of rel dir */
        string_append_range( file, dir.dir.ptr + 2, dir.dir.ptr + 2 + dir.dir.len - 2  );
        break;
    }

# ifdef DEBUG
    if ( DEBUG_SEARCH && ( root.flags || dir.flags ) )
        printf( "%d x %d = %d (%s)\n", root.flags, dir.flags,
                grid[ root.flags ][ dir.flags ], file->value );
# endif

    /*
     * Now do the special :P modifier when no file was present.
     *  (none)      (none)
     *  [dir1.dir2] [dir1]
     *  [dir]       [000000]
     *  [.dir]      (none)
     *  []      []
     */

    if ( ( file->value[ file->size - 1 ] == ']' ) && f->parent )
    {
        char * p = file->value + file->size;
        while ( p-- > file->value )
        {
            if ( *p == '.' )
            {
                /* If we've truncated everything and left with '[',
                   return empty string. */
                if ( p == file->value + 1 )
                    string_truncate( file, 0 );
                else
                {
                    string_truncate( file, p - file->value );
                    string_push_back( file, ']' );
                }
                break;
            }
            
            if ( *p == '-' )
            {
                /* handle .- or - */
                if ( ( p > file->value ) && ( p[ -1 ] == '.' ) )
                    --p;

                *p++ = ']';
                break;
            }
            
            if ( *p == '[' )
            {
                if ( p[ 1 ] == ']' )
                {
                    /* CONSIDER: I don't see any use of this code. We immediately
                       break, and 'p' is a local variable. */
                    p += 2;
                }
                else
                {
                    string_truncate( file, p - file->value );
                    string_append( file, "[000000]" );
                }
                break;
            }
        }
    }

    /* Now copy the file pieces. */
    if ( f->f_base.len )
    {
        string_append_range( file, f->f_base.ptr, f->f_base.ptr + f->f_base.len  );
    }

    /* If there is no suffix, we append a "." onto all generated names. This
     * keeps VMS from appending its own (wrong) idea of what the suffix should
     * be.
     */
    if ( f->f_suffix.len )
        string_append_range( file, f->f_suffix.ptr, f->f_suffix.ptr + f->f_suffix.len  );
    else if ( binding && f->f_base.len )
        string_push_back( file, '.' );

    if ( f->f_member.len )
    {
        string_push_back( file, '(' );
        string_append_range( file, f->f_member.ptr, f->f_member.ptr + f->f_member.len  );
        string_push_back( file, ')' );
    }

# ifdef DEBUG
    if ( DEBUG_SEARCH )
        printf( "built %.*s + %.*s / %.*s suf %.*s mem %.*s -> %s\n",
               f->f_root.len, f->f_root.ptr,
               f->f_dir.len, f->f_dir.ptr,
               f->f_base.len, f->f_base.ptr,
               f->f_suffix.len, f->f_suffix.ptr,
               f->f_member.len, f->f_member.ptr,
               file->value );
# endif
}
Example #19
0
void
var_defines( char *const* e, int preprocess )
{
    string buf[1];

    string_new( buf );

	for( ; *e; e++ )
	{
	    char *val;

# ifdef OS_MAC
	    /* On the mac (MPW), the var=val is actually var\0val */
	    /* Think different. */
	
	    if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )
# else
	    if( val = strchr( *e, '=' ) )
# endif
	    {
		LIST *l = L0;
		char *pp, *p;
# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT
                char split = '\0';
# else
# ifdef OS_MAC
		char split = ',';
# else
		char split = ' ';
# endif
# endif
                size_t len = strlen(val + 1);

                int quoted = val[1] == '"' && val[len] == '"' && len > 1;
                
                if ( quoted && preprocess )
                {
                    string_append_range( buf, val + 2, val + len );
                    l = list_new( l, newstr( buf->value ) );
                    string_truncate( buf, 0 );
                }
                else
                {
                    /* Split *PATH at :'s, not spaces */

                    if( val - 4 >= *e )
                    {
                        if( !strncmp( val - 4, "PATH", 4 ) ||
                            !strncmp( val - 4, "Path", 4 ) ||
                            !strncmp( val - 4, "path", 4 ) )
			    split = SPLITPATH;
                    }

                    /* Do the split */

                    for(
                        pp = val + 1;
                        preprocess && (p = strchr( pp, split )) != 0;
                        pp = p + 1 )
                    {
                        string_append_range( buf, pp, p );
                        l = list_new( l, newstr( buf->value ) );
                        string_truncate( buf, 0 );
                    }

                    l = list_new( l, newstr( pp ) );
                }

		/* Get name */
                string_append_range( buf, *e, val );
		var_set( buf->value, l, VAR_SET );
                string_truncate( buf, 0 );
	    }
	}
        string_free( buf );
}
Example #20
0
void var_defines( struct module_t * module, char * const * e, int preprocess )
{
    string buf[ 1 ];

    string_new( buf );

    for ( ; *e; ++e )
    {
        char * val;

        if ( ( val = strchr( *e, '=' ) )
#if defined( OS_MAC )
            /* On the mac (MPW), the var=val is actually var\0val */
            /* Think different. */
            || ( val = *e + strlen( *e ) )
#endif
        )
        {
            LIST * l = L0;
            size_t const len = strlen( val + 1 );
            int const quoted = ( val[ 1 ] == '"' ) && ( val[ len ] == '"' ) &&
                ( len > 1 );

            if ( quoted && preprocess )
            {
                string_append_range( buf, val + 2, val + len );
                l = list_push_back( l, object_new( buf->value ) );
                string_truncate( buf, 0 );
            }
            else
            {
                char * p;
                char * pp;
                char split =
#if defined( OPT_NO_EXTERNAL_VARIABLE_SPLIT )
                    '\0'
#elif defined( OS_MAC )
                    ','
#else
                    ' '
#endif
                    ;

                /* Split *PATH at :'s, not spaces. */
                if ( val - 4 >= *e )
                {
                    if ( !strncmp( val - 4, "PATH", 4 ) ||
                        !strncmp( val - 4, "Path", 4 ) ||
                        !strncmp( val - 4, "path", 4 ) )
                        split = SPLITPATH;
                }

                /* Do the split. */
                for
                (
                    pp = val + 1;
                    preprocess && ( ( p = strchr( pp, split ) ) != 0 );
                    pp = p + 1
                )
                {
                    string_append_range( buf, pp, p );
                    l = list_push_back( l, object_new( buf->value ) );
                    string_truncate( buf, 0 );
                }

                l = list_push_back( l, object_new( pp ) );
            }

            /* Get name. */
            string_append_range( buf, *e, val );
            {
                OBJECT * const varname = object_new( buf->value );
                var_set( module, varname, l, VAR_SET );
                object_free( varname );
            }
            string_truncate( buf, 0 );
        }
    }
    string_free( buf );
}
Example #21
0
void ShortPathToLongPath( char * short_path, string * out )
{
    const char * new_element;
    unsigned long saved_size;
    char * p;

    if ( short_path[0] == '\0' )
    {
        return;
    }

    if ( short_path[0] == '\\' && short_path[1] == '\0')
    {
        string_push_back( out, '\\' );
        return;
    }

    if ( short_path[1] == ':' &&
        ( short_path[2] == '\0' ||
        ( short_path[2] == '\\' && short_path[3] == '\0' ) ) )
    {
        string_push_back( out, toupper( short_path[0] ) );
        string_push_back( out, ':' );
        string_push_back( out, '\\' );
        return;
    }
    
    /* '/' already handled. */
    if ( ( p = strrchr( short_path, '\\' ) ) )
    {
        char saved;
        new_element = p + 1;

        /* special case \ */
        if ( p == short_path )
            ++p;
        
        /* special case D:\ */
        if ( p == short_path + 2  && short_path[1] == ':' )
            ++p;

        saved = *p;
        *p = '\0';
        path_write_key( short_path, out );
        *p = saved;
    }
    else
    {
        new_element = short_path;
    }

    if ( out->size && out->value[ out->size - 1 ] != '\\' )
    {
        string_push_back( out, '\\' );
    }
    
    saved_size = out->size;
    string_append( out, new_element );

    if ( ! ( new_element[0] == '.' && new_element[1] == '\0' ||
        new_element[0] == '.' && new_element[1] == '.'
        && new_element[2] == '\0' ) )
    {
        WIN32_FIND_DATA fd;
        HANDLE hf = 0;
        hf = FindFirstFile( out->value, &fd );

        /* If the file exists, replace the name. */
        if ( hf != INVALID_HANDLE_VALUE )
        {
            string_truncate( out, saved_size );
            string_append( out, fd.cFileName );
            FindClose( hf );
        }
    }
}
Example #22
0
void
timestamp( 
	char	*target,
	time_t	*time )
{
	PATHNAME f1, f2;
	BINDING	binding, *b = &binding;
	string buf[1];

# ifdef DOWNSHIFT_PATHS
        string path; 
	char *p;

        string_copy( &path, target );
        p = path.value;

	do
            *p = tolower( *p );
	while( *p++ );

	target = path.value;
# endif
        string_new( buf );

	if( !bindhash )
	    bindhash = hashinit( sizeof( BINDING ), "bindings" );

	/* Quick path - is it there? */

	b->name = target;
	b->time = b->flags = 0;
	b->progress = BIND_INIT;

	if( hashenter( bindhash, (HASHDATA **)&b ) )
	    b->name = newstr( target );		/* never freed */

	if( b->progress != BIND_INIT )
	    goto afterscanning;

	b->progress = BIND_NOENTRY;

	/* Not found - have to scan for it */

	path_parse( target, &f1 );

	/* Scan directory if not already done so */

	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    path_parent( &f2 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_dirscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

	/* Scan archive if not already done so */

	if( f1.f_member.len )
	{
	    BINDING binding, *b = &binding;

	    f2 = f1;
	    f2.f_grist.len = 0;
	    f2.f_member.len = 0;
            string_truncate( buf, 0 );
	    path_build( &f2, buf, 0 );

	    b->name = buf->value;
	    b->time = b->flags = 0;
	    b->progress = BIND_INIT;

	    if( hashenter( bindhash, (HASHDATA **)&b ) )
		b->name = newstr( buf->value );	/* never freed */

	    if( !( b->flags & BIND_SCANNED ) )
	    {
		file_archscan( buf->value, time_enter, bindhash );
		b->flags |= BIND_SCANNED;
	    }
	}

    afterscanning:

	if( b->progress == BIND_SPOTTED )
	{
	    if( file_time( b->name, &b->time ) < 0 )
		b->progress = BIND_MISSING;
	    else
		b->progress = BIND_FOUND;
	}

	*time = b->progress == BIND_FOUND ? b->time : 0;
        string_free( buf );
# ifdef DOWNSHIFT_PATHS
        string_free( &path );
#endif
}
Example #23
0
void file_dirscan( char * dir, scanback func, void * closure )
{
    PROFILE_ENTER( FILE_DIRSCAN );

    file_info_t * d = 0;

    dir = short_path_to_long_path( dir );

    /* First enter directory itself */

    d = file_query( dir );

    if ( !d || !d->is_dir )
    {
        PROFILE_EXIT( FILE_DIRSCAN );
        return;
    }

    if ( !d->files )
    {
        PATHNAME f;
        string filespec[ 1 ];
        string filename[ 1 ];
        long handle;
        int ret;
        struct _finddata_t finfo[ 1 ];
        LIST * files = L0;
        int d_length = strlen( d->name );

        memset( (char *)&f, '\0', sizeof( f ) );

        f.f_dir.ptr = d->name;
        f.f_dir.len = d_length;

        /* Now enter contents of directory */

        /* Prepare file search specification for the findfirst() API. */
        if ( d_length == 0 )
            string_copy( filespec, ".\\*" );
        else
        {
            /*
             * We can not simply assume the given folder name will never include
             * its trailing path separator or otherwise we would not support the
             * Windows root folder specified without its drive letter, i.e. '\'.
             */
            char trailingChar = d->name[ d_length - 1 ] ;
            string_copy( filespec, d->name );
            if ( ( trailingChar != '\\' ) && ( trailingChar != '/' ) )
                string_append( filespec, "\\" );
            string_append( filespec, "*" );
        }

        if ( DEBUG_BINDSCAN )
            printf( "scan directory %s\n", dir );

        #if defined(__BORLANDC__) && __BORLANDC__ < 0x550
        if ( ret = findfirst( filespec->value, finfo, FA_NORMAL | FA_DIREC ) )
        {
            string_free( filespec );
            PROFILE_EXIT( FILE_DIRSCAN );
            return;
        }

        string_new ( filename );
        while ( !ret )
        {
            file_info_t * ff = 0;

            f.f_base.ptr = finfo->ff_name;
            f.f_base.len = strlen( finfo->ff_name );

            string_truncate( filename, 0 );
            path_build( &f, filename );

            files = list_new( files, newstr(filename->value) );
            ff = file_info( filename->value );
            ff->is_file = finfo->ff_attrib & FA_DIREC ? 0 : 1;
            ff->is_dir = finfo->ff_attrib & FA_DIREC ? 1 : 0;
            ff->size = finfo->ff_fsize;
            ff->time = (finfo->ff_ftime << 16) | finfo->ff_ftime;

            ret = findnext( finfo );
        }
        # else
        handle = _findfirst( filespec->value, finfo );

        if ( ret = ( handle < 0L ) )
        {
            string_free( filespec );
            PROFILE_EXIT( FILE_DIRSCAN );
            return;
        }

        string_new( filename );
        while ( !ret )
        {
            file_info_t * ff = 0;

            f.f_base.ptr = finfo->name;
            f.f_base.len = strlen( finfo->name );

            string_truncate( filename, 0 );
            path_build( &f, filename, 0 );

            files = list_new( files, newstr( filename->value ) );
            ff = file_info( filename->value );
            ff->is_file = finfo->attrib & _A_SUBDIR ? 0 : 1;
            ff->is_dir = finfo->attrib & _A_SUBDIR ? 1 : 0;
            ff->size = finfo->size;
            ff->time = finfo->time_write;

            ret = _findnext( handle, finfo );
        }

        _findclose( handle );
        # endif
        string_free( filename );
        string_free( filespec );

        d->files = files;
    }

    /* Special case \ or d:\ : enter it */
    {
        unsigned long len = strlen(d->name);
        if ( len == 1 && d->name[0] == '\\' )
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
        else if ( len == 3 && d->name[1] == ':' ) {
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
            /* We've just entered 3-letter drive name spelling (with trailing
               slash), into the hash table. Now enter two-letter variant,
               without trailing slash, so that if we try to check whether
               "c:" exists, we hit it.

               Jam core has workarounds for that. Given:
                  x = c:\whatever\foo ;
                  p = $(x:D) ;
                  p2 = $(p:D) ;
               There will be no trailing slash in $(p), but there will be one
               in $(p2). But, that seems rather fragile.                
            */
            d->name[2] = 0;
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
        }
    }

    /* Now enter contents of directory */
    if ( d->files )
    {
        LIST * files = d->files;
        while ( files )
        {
            file_info_t * ff = file_info( files->string );
            (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
            files = list_next( files );
        }
    }

    PROFILE_EXIT( FILE_DIRSCAN );
}
Example #24
0
TARGET* search_for_target ( char * name, LIST* search_path )
{
    PATHNAME f[1];
    string buf[1];
    LOCATED_TARGET lt, *lta = &lt;
    time_t time;
    int found = 0;
    TARGET* result;

    string_new( buf );

	path_parse( name, f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    while( search_path )
    {
        f->f_root.ptr = search_path->string;
        f->f_root.len = strlen( search_path->string );

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        lt.file_name = buf->value ;

        if (! located_targets )
            located_targets = hashinit( sizeof(LOCATED_TARGET),
                                        "located targets" );


        if ( hashcheck( located_targets, (HASHDATA **)&lta ) )
        {
            return lta->target;
        }

        timestamp( buf->value, &time );
        if (time)
        {
            found = 1;
            break;
        }

        search_path = list_next( search_path );
    }

    if ( ! found )
    {
        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        timestamp( buf->value, &time );        
    }

    result = bindtarget( name );
    result->boundname = newstr( buf->value );
    result->time = time;
    result->binding = time ? T_BIND_EXISTS : T_BIND_MISSING;

    call_bind_rule( result->name, result->boundname );
    
    string_free( buf );

    return result;

}
Example #25
0
LIST *
var_expand( 
	LIST	*l,
	char	*in,
	char	*end,
	LOL	*lol,
	int	cancopyin )
{
    char out_buf[ MAXSYM ];
    string buf[1];
    string out1[1]; /* Temporary buffer */
    size_t prefix_length;
    char *out;
    char *inp = in;
    char *ov;		/* for temp copy of variable in outbuf */
    int depth;

    if( DEBUG_VAREXP )
        printf( "expand '%.*s'\n", end - in, in );

    /* This gets alot of cases: $(<) and $(>) */

    if( in[0] == '$' && in[1] == '(' && in[3] == ')' && !in[4] )
    {
        switch( in[2] )
        {
        case '1':
        case '<':
            return list_copy( l, lol_get( lol, 0 ) );

        case '2':
        case '>':
            return list_copy( l, lol_get( lol, 1 ) );
        }
    }

    /* Just try simple copy of in to out. */

    while( in < end )
        if( *in++ == '$' && *in == '(' ) 
            goto expand;

    /* No variables expanded - just add copy of input string to list. */

    /* Cancopyin is an optimization: if the input was already a list */
    /* item, we can use the copystr() to put it on the new list. */
    /* Otherwise, we use the slower newstr(). */

    if( cancopyin ) 
    {
        return list_new( l, copystr( inp ) );
    }
    else
    {
        LIST* r;
        string_new( buf );
        string_append_range( buf, inp, end );

        r = list_new( l, newstr( buf->value) );
        string_free( buf );
        return r;
    }

expand:
    string_new( buf );
    string_append_range( buf, inp, in - 1); /* copy the part before '$'. */
    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                   ^                   ^
     *                   in                  end
     * Output so far:
     *
     *  stuff-in-outbuf $
     *  ^                ^
     *  out_buf          out
     *
     *
     * We just copied the $ of $(...), so back up one on the output.
     * We now find the matching close paren, copying the variable and
     * modifiers between the $( and ) temporarily into out_buf, so that
     * we can replace :'s with MAGIC_COLON.  This is necessary to avoid
     * being confused by modifier values that are variables containing
     * :'s.  Ugly.
     */

    depth = 1;
    inp = ++in; /* skip over the '(' */

    while( in < end && depth )
    {
        switch( *in++ )
        {
        case '(': depth++; break;
        case ')': depth--; break;
        }
    }

    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                    ^        ^         ^
     *                    inp      in        end
     */
    prefix_length = buf->size;
    string_append_range( buf, inp, in - 1 );

    out = buf->value + prefix_length;
    for ( ov = out; ov < buf->value + buf->size; ++ov )
    {
        switch( *ov )
        {
        case ':': *ov = MAGIC_COLON; break;
        case '[': *ov = MAGIC_LEFT; break;
        case ']': *ov = MAGIC_RIGHT; break;
        }
    }

    /*
     * Input so far (ignore blanks):
     *
     *  stuff-in-outbuf $(variable) remainder
     *                              ^        ^
     *                              in       end
     * Output so far:
     *
     *  stuff-in-outbuf variable
     *  ^               ^       ^
     *  out_buf         out     ov
     *
     * Later we will overwrite 'variable' in out_buf, but we'll be
     * done with it by then.  'variable' may be a multi-element list, 
     * so may each value for '$(variable element)', and so may 'remainder'.
     * Thus we produce a product of three lists.
     */

    {
        LIST *variables = 0;
        LIST *remainder = 0;
        LIST *vars;

        /* Recursively expand variable name & rest of input */

        if( out < ov )
            variables = var_expand( L0, out, ov, lol, 0 );
        if( in < end )
            remainder = var_expand( L0, in, end, lol, 0 );

        /* Now produce the result chain */

        /* For each variable name */

        for( vars = variables; vars; vars = list_next( vars ) )
        {
            LIST *value, *evalue = 0;
            char *colon;
            char *bracket;
            string variable[1];
            char *varname;
            int sub1 = 0, sub2 = -1;
            VAR_EDITS edits;

            /* Look for a : modifier in the variable name */
            /* Must copy into varname so we can modify it */

            string_copy( variable, vars->string );
            varname = variable->value;

            if( colon = strchr( varname, MAGIC_COLON ) )
            {
                string_truncate( variable, colon - varname );
                var_edit_parse( colon + 1, &edits );
            }

            /* Look for [x-y] subscripting */
            /* sub1 and sub2 are x and y. */

            if ( bracket = strchr( varname, MAGIC_LEFT ) )
            {
                /*
                ** Make all syntax errors in [] subscripting
                ** result in the same behavior: silenty return an empty
                ** expansion (by setting sub2 = 0). Brute force parsing;
                ** May get moved into yacc someday.
                */

                char *s = bracket + 1;

                string_truncate( variable, bracket - varname );

                do  /* so we can use "break" */
                {
                    /* Allow negative indexes. */
                    if (! isdigit( *s ) && ! ( *s == '-') )
                    {
                        sub2 = 0;
                        break;
                    }
                    sub1 = atoi(s);

                    /* Skip over the first symbol, which is either a digit or dash. */
                    s++;
                    while ( isdigit( *s ) ) s++;

                    if ( *s == MAGIC_RIGHT )
                    {
                        sub2 = sub1;
                        break;
                    }

                    if ( *s != '-')
                    {
                        sub2 = 0;
                        break;
                    }

                    s++;

                    if ( *s == MAGIC_RIGHT )
                    {
                        sub2 = -1;
                        break;
                    }

                    if (! isdigit( *s ) && ! ( *s == '-') )
                    {
                        sub2 = 0;
                        break;
                    }

                    /* First, compute the index of the last element. */
                    sub2 = atoi(s);               
                    s++;
                    while ( isdigit( *s ) ) s++;

                    if ( *s != MAGIC_RIGHT)
                        sub2 = 0;

                } while (0);

                /*
                ** Anything but the end of the string, or the colon
                ** introducing a modifier is a syntax error.
                */

                s++;                
                if (*s && *s != MAGIC_COLON)
                    sub2 = 0;

                *bracket = '\0';
            }

            /* Get variable value, specially handling $(<), $(>), $(n) */
		
            if( varname[0] == '<' && !varname[1] )
                value = lol_get( lol, 0 );
            else if( varname[0] == '>' && !varname[1] )
                value = lol_get( lol, 1 );
            else if( varname[0] >= '1' && varname[0] <= '9' && !varname[1] )
                value = lol_get( lol, varname[0] - '1' );
            else 
                value = var_get( varname );

            /* Handle negitive indexes: part two. */
            {
                int length = list_length( value );

                if (sub1 < 0)
                    sub1 = length + sub1;
                else
                    sub1 -= 1;

                if (sub2 < 0)
                    sub2 = length + 1 + sub2 - sub1;
                else
                    sub2 -= sub1;
                /*
                ** The "sub2 < 0" test handles the semantic error
                ** of sub2 < sub1.
                */
                if ( sub2 < 0 )
                    sub2 = 0;
            }



            /* The fast path: $(x) - just copy the variable value. */
            /* This is only an optimization */

            if( out == out_buf && !bracket && !colon && in == end )
            {
                string_free( variable );
                l = list_copy( l, value );
                continue;
            }

            /* Handle start subscript */

            while( sub1 > 0 && value )
                --sub1, value = list_next( value );

            /* Empty w/ :E=default? */

            if( !value && colon && edits.empty.ptr )
                evalue = value = list_new( L0, newstr( edits.empty.ptr ) );

            /* For each variable value */

            string_new( out1 );
            for( ; value; value = list_next( value ) )
            {
                LIST *rem;
                size_t postfix_start;

                /* Handle end subscript (length actually) */

                if( sub2 >= 0 && --sub2 < 0 )
                    break;

                string_truncate( buf, prefix_length );

                /* Apply : mods, if present */

                if( colon && edits.filemods )
                    var_edit_file( value->string, out1, &edits );
                else
                    string_append( out1, value->string );

                if( colon && ( edits.upshift || edits.downshift || edits.to_slashes || edits.to_windows ) )
                    var_edit_shift( out1, &edits );

                /* Handle :J=joinval */
                /* If we have more values for this var, just */
                /* keep appending them (with the join value) */
                /* rather than creating separate LIST elements. */

                if( colon && edits.join.ptr && 
                    ( list_next( value ) || list_next( vars ) ) )
                {
                    string_append( out1, edits.join.ptr );
                    continue;
                }

                string_append( buf, out1->value );
                string_free( out1 );
                string_new( out1 );

                /* If no remainder, append result to output chain. */

                if( in == end )
                {
                    l = list_new( l, newstr( buf->value ) );
                    continue;
                }

                /* For each remainder, append the complete string */
                /* to the output chain. */
                /* Remember the end of the variable expansion so */
                /* we can just tack on each instance of 'remainder' */

                postfix_start = buf->size;

                for( rem = remainder; rem; rem = list_next( rem ) )
                {
                    string_truncate( buf, postfix_start );
                    string_append( buf, rem->string );
                    l = list_new( l, newstr( buf->value ) );
                }
            }
            string_free( out1 );

            /* Toss used empty */

            if( evalue )
                list_free( evalue );

            string_free( variable );
        }

        /* variables & remainder were gifts from var_expand */
        /* and must be freed */

        if( variables )
            list_free( variables );
        if( remainder)
            list_free( remainder );

        if( DEBUG_VAREXP )
        {
            printf( "expanded to " );
            list_print( l );
            printf( "\n" );
        }

        string_free( buf );
        return l;
    }
}
Example #26
0
void file_dirscan( char * dir, scanback func, void * closure )
{
    PATHNAME f;
    string filename[ 1 ];
    unsigned char fullPath[ 512 ];

    FSSpec spec;
    WDPBRec vol;
    Str63 volName;
    CInfoPBRec lastInfo;
    int index = 1;

    /* First enter directory itself. */

    memset( (char *)&f, '\0', sizeof( f ) );

    f.f_dir.ptr = dir;
    f.f_dir.len = strlen(dir);

    if ( DEBUG_BINDSCAN )
        printf( "scan directory %s\n", dir );

    /* Special case ":" - enter it */

    if ( ( f.f_dir.len == 1 ) && ( f.f_dir.ptr[0] == ':' ) )
        (*func)( closure, dir, 0 /* not stat()'ed */, (time_t)0 );

    /* Now enter contents of directory */

    vol.ioNamePtr = volName;

    if ( PBHGetVolSync( &vol ) )
        return;

    CopyC2PStr( dir, fullPath );

    if ( FSMakeFSSpec( vol.ioWDVRefNum, vol.ioWDDirID, fullPath, &spec ) )
        return;

    lastInfo.dirInfo.ioVRefNum   = spec.vRefNum;
    lastInfo.dirInfo.ioDrDirID   = spec.parID;
    lastInfo.dirInfo.ioNamePtr   = spec.name;
    lastInfo.dirInfo.ioFDirIndex = 0;
    lastInfo.dirInfo.ioACUser    = 0;

    if ( PBGetCatInfoSync( &lastInfo ) )
        return;

    if ( !( lastInfo.dirInfo.ioFlAttrib & 0x10 ) )
        return;

    /* ioDrDirID must be reset each time. */
    spec.parID = lastInfo.dirInfo.ioDrDirID;

    string_new( filename );
    for ( ; ; )
    {
        lastInfo.dirInfo.ioVRefNum  = spec.vRefNum;
        lastInfo.dirInfo.ioDrDirID  = spec.parID;
        lastInfo.dirInfo.ioNamePtr  = fullPath;
        lastInfo.dirInfo.ioFDirIndex = index++;

        if ( PBGetCatInfoSync( &lastInfo ) )
            return;

        f.f_base.ptr = (char *)fullPath + 1;
        f.f_base.len = *fullPath;

        string_truncate( filename, 0 );
        path_build( &f, filename, 0 );
        (*func)( closure, filename->value, 0 /* not stat()'ed */, (time_t)0 );
    }
    string_free( filename );
}
Example #27
0
OBJECT *
search(
    OBJECT * target,
    time_t *time,
    OBJECT * * another_target,
    int file
)
{
    PATHNAME f[1];
    LIST   * varlist;
    string   buf[1];
    int      found = 0;
    /* Will be set to 1 if target location is specified via LOCATE. */
    int      explicitly_located = 0;
    OBJECT * boundname = 0;
    OBJECT * varname;

    if ( another_target )
        *another_target = 0;

    if (! explicit_bindings )
        explicit_bindings = hashinit( sizeof(BINDING),
                                      "explicitly specified locations");

    string_new( buf );
    /* Parse the filename */

    path_parse( object_str( target ), f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    varname = object_new( "LOCATE" );
    varlist = var_get( varname );
    object_free( varname );
    if ( varlist )
    {
        OBJECT * key;
        f->f_root.ptr = object_str( varlist->value );
        f->f_root.len = strlen( object_str( varlist->value ) );

        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "locate %s: %s\n", object_str( target ), buf->value );

        explicitly_located = 1;

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
        found = 1;
    }
    else if ( ( varname = object_new( "SEARCH" ),
                varlist = var_get( varname ),
                object_free( varname ),
                varlist ) )
    {
        while ( varlist )
        {
            BINDING b, *ba = &b;
            file_info_t *ff;
            OBJECT * key;
            OBJECT * test_path;

            f->f_root.ptr = object_str( varlist->value );
            f->f_root.len = strlen( object_str( varlist->value ) );

            string_truncate( buf, 0 );
            path_build( f, buf, 1 );

            if ( DEBUG_SEARCH )
                printf( "search %s: %s\n", object_str( target ), buf->value );

            test_path = object_new( buf->value );
            key = path_as_key( test_path );
            object_free( test_path );
            ff = file_query( key );
            timestamp( key, time );

            b.binding = key;

            if ( hashcheck( explicit_bindings, (HASHDATA**)&ba ) )
            {
                if ( DEBUG_SEARCH )
                    printf(" search %s: found explicitly located target %s\n",
                           object_str( target ), object_str( ba->target ) );
                if ( another_target )
                    *another_target = ba->target;
                found = 1;
                object_free( key );
                break;
            }
            else if ( ff && ff->time )
            {
                if ( !file || ff->is_file )
                {
                    found = 1;
                    object_free( key );
                    break;
                }
            }
            object_free( key );

            varlist = list_next( varlist );
        }
    }

    if ( !found )
    {
        /* Look for the obvious */
        /* This is a questionable move.  Should we look in the */
        /* obvious place if SEARCH is set? */
        OBJECT * key;

        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "search %s: %s\n", object_str( target ), buf->value );

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
    }

    boundname = object_new( buf->value );
    string_free( buf );

    if ( explicitly_located )
    {
        BINDING b;
        BINDING * ba = &b;
        OBJECT * key = path_as_key( boundname );
        b.binding = key;
        b.target = target;
        /* CONSIDER: we probably should issue a warning is another file
           is explicitly bound to the same location. This might break
           compatibility, though. */
        if ( !hashenter( explicit_bindings, (HASHDATA * *)&ba ) )
        {
            object_free( key );
        }
    }

    /* prepare a call to BINDRULE if the variable is set */
    call_bind_rule( target, boundname );

    return boundname;
}
Example #28
0
OBJECT *
search(
    OBJECT * target,
    time_t *time,
    OBJECT * * another_target,
    int file
)
{
    PATHNAME f[1];
    LIST   * varlist;
    string   buf[1];
    int      found = 0;
    /* Will be set to 1 if target location is specified via LOCATE. */
    int      explicitly_located = 0;
    OBJECT * boundname = 0;

    if ( another_target )
        *another_target = 0;

    if (! explicit_bindings )
        explicit_bindings = hashinit( sizeof(BINDING),
                                     "explicitly specified locations");

    string_new( buf );
    /* Parse the filename */

    path_parse( object_str( target ), f );

    f->f_grist.ptr = 0;
    f->f_grist.len = 0;

    varlist = var_get( root_module(), constant_LOCATE );
    if ( !list_empty( varlist ) )
    {
        OBJECT * key;
        f->f_root.ptr = object_str( list_front( varlist ) );
        f->f_root.len = strlen( object_str( list_front( varlist ) ) );

        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "locate %s: %s\n", object_str( target ), buf->value );

        explicitly_located = 1;

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
        found = 1;
    }
    else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) )
    {
        LISTITER iter = list_begin( varlist ), end = list_end( varlist );
        for ( ; iter != end; iter = list_next( iter ) )
        {
            BINDING * ba;
            file_info_t *ff;
            OBJECT * key;
            OBJECT * test_path;

            f->f_root.ptr = object_str( list_item( iter ) );
            f->f_root.len = strlen( object_str( list_item( iter ) ) );

            string_truncate( buf, 0 );
            path_build( f, buf, 1 );

            if ( DEBUG_SEARCH )
                printf( "search %s: %s\n", object_str( target ), buf->value );

            test_path = object_new( buf->value );
            key = path_as_key( test_path );
            object_free( test_path );
            ff = file_query( key );
            timestamp( key, time );

            if ( ( ba = (BINDING *)hash_find( explicit_bindings, key ) ) )
            {
                if ( DEBUG_SEARCH )
                    printf(" search %s: found explicitly located target %s\n",
                           object_str( target ), object_str( ba->target ) );
                if ( another_target )
                    *another_target = ba->target;
                found = 1;
                object_free( key );
                break;
            }
            else if ( ff && ff->time )
            {
                if ( !file || ff->is_file )
                {
                    found = 1;
                    object_free( key );
                    break;
                }
            }
            object_free( key );
        }
    }

    if ( !found )
    {
        /* Look for the obvious */
        /* This is a questionable move.  Should we look in the */
        /* obvious place if SEARCH is set? */
        OBJECT * key;

        f->f_root.ptr = 0;
        f->f_root.len = 0;

        string_truncate( buf, 0 );
        path_build( f, buf, 1 );

        if ( DEBUG_SEARCH )
            printf( "search %s: %s\n", object_str( target ), buf->value );

        key = object_new( buf->value );
        timestamp( key, time );
        object_free( key );
    }

    boundname = object_new( buf->value );
    string_free( buf );

    if ( explicitly_located )
    {
        int found;
        BINDING * ba;
        OBJECT * key = path_as_key( boundname );
        /* CONSIDER: we probably should issue a warning is another file
           is explicitly bound to the same location. This might break
           compatibility, though. */
        ba = (BINDING *)hash_insert( explicit_bindings, key, &found );
        if ( !found )
        {
            ba->binding = key;
            ba->target = target;
        }
        else
        {
            object_free( key );
        }
    }

    /* prepare a call to BINDRULE if the variable is set */
    call_bind_rule( target, boundname );

    return boundname;
}
Example #29
0
void file_dirscan( OBJECT * dir, scanback func, void * closure )
{
    PROFILE_ENTER( FILE_DIRSCAN );

    file_info_t * d = 0;

    d = file_query( dir );

    if ( !d || !d->is_dir )
    {
        PROFILE_EXIT( FILE_DIRSCAN );
        return;
    }

    if ( ! d->files )
    {
        LIST* files = L0;
        PATHNAME f;
        DIR *dd;
        STRUCT_DIRENT *dirent;
        string filename[1];
        const char * dirstr = object_str( dir );

        /* First enter directory itself */

        memset( (char *)&f, '\0', sizeof( f ) );

        f.f_dir.ptr = dirstr;
        f.f_dir.len = strlen( dirstr );

        dirstr = *dirstr ? dirstr : ".";

        /* Now enter contents of directory. */

        if ( !( dd = opendir( dirstr ) ) )
        {
            PROFILE_EXIT( FILE_DIRSCAN );
            return;
        }

        if ( DEBUG_BINDSCAN )
            printf( "scan directory %s\n", dirstr );

        string_new( filename );
        while ( ( dirent = readdir( dd ) ) )
        {
            OBJECT * filename_obj;
            # ifdef old_sinix
            /* Broken structure definition on sinix. */
            f.f_base.ptr = dirent->d_name - 2;
            # else
            f.f_base.ptr = dirent->d_name;
            # endif
            f.f_base.len = strlen( f.f_base.ptr );

            string_truncate( filename, 0 );
            path_build( &f, filename, 0 );

            filename_obj = object_new( filename->value );
            files = list_new( files, filename_obj );
            file_query( filename_obj );
        }
        string_free( filename );

        closedir( dd );

        d->files = files;
    }

    /* Special case / : enter it */
    {
        if ( strcmp( object_str( d->name ), "/" ) == 0 )
            (*func)( closure, d->name, 1 /* stat()'ed */, d->time );
    }

    /* Now enter contents of directory */
    if ( d->files )
    {
        LIST * files = d->files;
        while ( files )
        {
            file_info_t * ff = file_info( files->value );
            (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
            files = list_next( files );
        }
    }

    PROFILE_EXIT( FILE_DIRSCAN );
}
Example #30
0
void var_string_to_file( const char * in, int insize, const char * out, LOL * lol )
{
    const char * ine = in+insize;
    FILE * out_file = 0;
    if ( strcmp( out, "STDOUT" ) == 0 )
    {
        out_file = stdout;
    }
    else if ( strcmp( out, "STDERR" ) == 0 )
    {
        out_file = stderr;
    }
    else
    {
        /* Handle "path to file" filenames. */
        string out_name;
        if ( out[0] == '"' && out[strlen(out) - 1] == '"' )
        {
            string_copy(&out_name,out+1);
            string_truncate(&out_name,out_name.size-1);
        }
        else
        {
            string_copy(&out_name,out);
        }
        out_file = fopen( out_name.value, "w" );
        if (!out_file)
        {
            printf( "failed to write output file '%s'!\n", out_name.value );
            exit( EXITBAD );
        }
        string_free(&out_name);
    }

    while( *in && in < ine )
    {
        int dollar = 0;
        const char * output_0 = in;
        const char * output_1 = in;

        /* Copy white space */

        while ( output_1 < ine && *output_1 && isspace( *output_1 ) )
        {
            ++output_1;
        }
        if ( output_0 < output_1 )
        {
            fwrite(output_0,output_1-output_0,1,out_file);
        }
        output_0 = output_1;

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

        while( output_1 < ine && *output_1 && !isspace( *output_1 ) )
        {
            if( output_1[0] == '$' && output_1[1] && output_1[1] == '(' )
            {
                dollar++;
            }
            ++output_1;
        }

        /* 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, (char*)output_0, (char*)output_1, lol, 0 );

            while ( l )
            {
                fputs( l->string, out_file );
                l = list_next( l );
                if ( l ) fputc( ' ', out_file );
            }

            list_free( l );
        }
        else if ( output_0 < output_1 )
        {
            fwrite(output_0,output_1-output_0,1,out_file);
        }
        
        in = output_1;
    }

    if ( out_file != stdout && out_file != stderr )
    {
        fflush( out_file );
        fclose( out_file );
    }
}