FreeBSD/contrib/amd/amd/readdir.c
/*
 * Create a chain of entries which are not linked.
 * -Erez Zadok <ezk@cs.columbia.edu>
 */
Create a chain of entries which are not linked.
-Erez Zadok 
Create a chain of entries which are not linked . - Erez Zadok
static nfsentry *
make_entry_chain(am_node *mp, const nfsentry *current_chain, int fully_browsable)
{
  static u_int last_cookie = (u_int) 2;	
  static nfsentry chain[MAX_CHAIN];
  static int max_entries = MAX_CHAIN;
  char *key;
  int num_entries = 0, i;
  u_int preflen = 0;
  nfsentry *retval = (nfsentry *) NULL;
  mntfs *mf;
  mnt_map *mmp;
  if (!mp) {
    plog(XLOG_DEBUG, "make_entry_chain: mp is (NULL)");
    return retval;
  }
  mf = mp->am_mnt;
  if (!mf) {
    plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt is (NULL)");
    return retval;
  }
  mmp = (mnt_map *) mf->mf_private;
  if (!mmp) {
    plog(XLOG_DEBUG, "make_entry_chain: mp->am_mnt->mf_private is (NULL)");
    return retval;
  }
  if (mp->am_pref)
    preflen = strlen(mp->am_pref);
  for (i = 0; i < NKVHASH; i++) {
    kv *k;
    for (k = mmp->kvhash[i]; k ; k = k->next) {
      key = k->key;
      if (!key)
	continue;
      if (STREQ(key, "/defaults"))
	continue;
      if (!fully_browsable && strchr(key, '*'))
	continue;
      if (preflen) {
	if (preflen > strlen(key))
	  continue;
	if (!NSTREQ(key, mp->am_pref, preflen))
	  continue;
	key += preflen;
      }
      if (!fully_browsable && strchr(key, '/'))
	continue;
      if (key_already_in_chain(key, current_chain))
	continue;
      if (num_entries >= max_entries) {
	plog(XLOG_DEBUG, "make_entry_chain: no more space in chain");
	if (num_entries > 0) {
	  chain[num_entries - 1].ne_nextentry = 0;
	  retval = &chain[0];
	}
	return retval;
      }
      ++last_cookie;
      chain[num_entries].ne_fileid = last_cookie;
      (void)memcpy(chain[num_entries].ne_cookie, &last_cookie,
	sizeof(last_cookie));
      chain[num_entries].ne_name = key;
      if (num_entries < max_entries - 1) {	
	chain[num_entries].ne_nextentry = &chain[num_entries + 1];
      }
      ++num_entries;
    } 
  } 
  if (num_entries > 0) {
    chain[num_entries - 1].ne_nextentry = 0;
    retval = &chain[0];
  }
  return retval;
}
static nfsentry * make_entry_chain ( am_node * mp , const nfsentry * current_chain , int fully_browsable ) { static u_int last_cookie = ( u_int ) 2 ; static nfsentry chain [ MAX_CHAIN ] ; static int max_entries = MAX_CHAIN ; char * key ; int num_entries = 0 , i ; u_int preflen = 0 ; nfsentry * retval = ( nfsentry * ) NULL ; mntfs * mf ; mnt_map * mmp ; if ( ! mp ) { plog ( XLOG_DEBUG , " " ) ; return retval ; } mf = mp -> am_mnt ; if ( ! mf ) { plog ( XLOG_DEBUG , " " ) ; return retval ; } mmp = ( mnt_map * ) mf -> mf_private ; if ( ! mmp ) { plog ( XLOG_DEBUG , " " ) ; return retval ; } if ( mp -> am_pref ) preflen = strlen ( mp -> am_pref ) ; for ( i = 0 ; i < NKVHASH ; i ++ ) { kv * k ; for ( k = mmp -> kvhash [ i ] ; k ; k = k -> next ) { key = k -> key ; if ( ! key ) continue ; if ( STREQ ( key , " " ) ) continue ; if ( ! fully_browsable && strchr ( key , ' ' ) ) continue ; if ( preflen ) { if ( preflen > strlen ( key ) ) continue ; if ( ! NSTREQ ( key , mp -> am_pref , preflen ) ) continue ; key += preflen ; } if ( ! fully_browsable && strchr ( key , ' ' ) ) continue ; if ( key_already_in_chain ( key , current_chain ) ) continue ; if ( num_entries >= max_entries ) { plog ( XLOG_DEBUG , " " ) ; if ( num_entries > 0 ) { chain [ num_entries - 1 ] . ne_nextentry = 0 ; retval = & chain [ 0 ] ; } return retval ; } ++ last_cookie ; chain [ num_entries ] . ne_fileid = last_cookie ; ( void ) memcpy ( chain [ num_entries ] . ne_cookie , & last_cookie , sizeof ( last_cookie ) ) ; chain [ num_entries ] . ne_name = key ; if ( num_entries < max_entries - 1 ) { chain [ num_entries ] . ne_nextentry = & chain [ num_entries + 1 ] ; } ++ num_entries ; } } if ( num_entries > 0 ) { chain [ num_entries - 1 ] . ne_nextentry = 0 ; retval = & chain [ 0 ] ; } return retval ; }
Create a chain of entries which are not linked.
Create a chain of entries which are not linked .
/* monotonically increasing */ /* iterate over keys */ /*
       * Skip unwanted entries which are either not real entries or
       * very difficult to interpret (wildcards...)  This test needs
       * lots of improvement.  Any takers?
       */ /* Skip '/defaults' */ /* Skip '*' */ /*
       * If the map has a prefix-string then check if the key starts with
       * this string, and if it does, skip over this prefix.  If it has a
       * prefix and it doesn't match the start of the key, skip it.
       */ /* no more '/' are allowed, unless browsable_dirs=full was used */ /* no duplicates allowed */ /* fill in a cell and link the entry */ /* out of space */ /* we have space.  put entry in next cell */ /* link to next one */ /* end of "while (k)" */ /* end of "for (i ... NKVHASH ..." */ /* terminate chain */