int do_list(
char *full_path,
char *start,
int fs_id,
struct options *opts,
char *entry_buffer)
{
int i = 0, printed_dot_info = 0;
int ret = -1;
int pvfs_dirent_incount;
char *name = NULL, *cur_file = NULL;
PVFS_handle cur_handle;
PVFS_sysresp_lookup lk_response;
PVFS_sysresp_readdirplus rdplus_response;
PVFS_sysresp_getattr getattr_response;
PVFS_credentials credentials;
PVFS_object_ref ref;
PVFS_ds_position token;
uint64_t dir_version = 0;
double begin = 0., end;
subdir *current, *head = NULL, *tail = NULL;
name = start;
memset(&lk_response,0,sizeof(PVFS_sysresp_lookup));
PVFS_util_gen_credentials(&credentials);
if (opts->list_recursive || opts->num_starts > 1)
{
printf("%s%s:
",full_path,start);
}
ret = PVFS_sys_lookup(fs_id, name, &credentials,
&lk_response, PVFS2_LOOKUP_LINK_NO_FOLLOW, NULL);// 。。。。
if(ret < 0)
{
PVFS_perror("PVFS_sys_lookup", ret);
return -1;
}
ref.handle = lk_response.ref.handle;
ref.fs_id = fs_id;
pvfs_dirent_incount = MAX_NUM_DIRENTS;
memset(&getattr_response,0,sizeof(PVFS_sysresp_getattr));
if (PVFS_sys_getattr(ref, PVFS_ATTR_SYS_ALL,
&credentials, &getattr_response, NULL) == 0)//
{
if ((getattr_response.attr.objtype == PVFS_TYPE_METAFILE) ||
(getattr_response.attr.objtype == PVFS_TYPE_SYMLINK) ||
((getattr_response.attr.objtype == PVFS_TYPE_DIRECTORY) &&
(opts->list_directory)))
{
char segment[128] = {0};
PVFS_sysresp_getparent getparent_resp;
PINT_remove_base_dir(name, segment, 128);
if (strcmp(segment,"") == 0)
{
snprintf(segment,128,"/");
}
if (getattr_response.attr.objtype == PVFS_TYPE_DIRECTORY)
{
if (PVFS_sys_getparent(ref.fs_id, name, &credentials,
&getparent_resp, NULL) == 0)
{
print_dot_and_dot_dot_info_if_required(
getparent_resp.parent_ref);
}
}
if (opts->list_long)
{
print_entry_attr(ref.handle, segment,
&getattr_response.attr, opts, entry_buffer);
}
else
{
print_entry(segment, ref.handle, ref.fs_id,
NULL,
0,
opts, entry_buffer);
}
return 0;
}
}
if (do_timing)
begin = Wtime();
token = 0;
do
{
memset(&rdplus_response, 0, sizeof(PVFS_sysresp_readdirplus));
ret = PVFS_sys_readdirplus(
ref, (!token ? PVFS_READDIR_START : token),
pvfs_dirent_incount, &credentials,
(opts->list_long) ?
PVFS_ATTR_SYS_ALL : PVFS_ATTR_SYS_ALL_NOSIZE,
&rdplus_response,
NULL);//readdirplus----------
if(ret < 0)
{
PVFS_perror("PVFS_sys_readdir", ret);
return -1;
}
if (dir_version == 0)
{
dir_version = rdplus_response.directory_version;
}
else if (opts->list_verbose)
{
if (dir_version != rdplus_response.directory_version)
{
fprintf(stderr, "*** directory changed! listing may "
"not be correct
");
dir_version = rdplus_response.directory_version;
}
}
if (!printed_dot_info)
{
/*
the list_all option prints files starting with .;
the almost_all option skips the '.', '..' printing
*/
print_dot_and_dot_dot_info_if_required(ref);
printed_dot_info = 1;
}
for(i = 0; i < rdplus_response.pvfs_dirent_outcount; i++)
{
cur_file = rdplus_response.dirent_array[i].d_name;
cur_handle = rdplus_response.dirent_array[i].handle;
print_entry(cur_file, cur_handle, fs_id,
&rdplus_response.attr_array[i],
rdplus_response.stat_err_array[i],
opts, entry_buffer);
PVFS_sys_attr *attr = &rdplus_response.attr_array[i];
if(attr->objtype == PVFS_TYPE_DIRECTORY && opts->list_recursive)
{
int path_len = strlen(start) + strlen(cur_file) + 1;
current = (subdir *) malloc(sizeof(subdir));
/* Prevent duplicate slashes in path */
if(start[strlen(start)-1] == '/')
{
current->path = (char *) malloc(path_len);
snprintf(current->path,path_len,"%s%s",start,cur_file);
}
else
{
current->path = (char *) malloc(path_len + 1);
snprintf(current->path,path_len+1,"%s/%s",start,cur_file);
}
/* Update linked list of subdirectories to recurse */
current->next = NULL;
if(!head)
{
head = current;
tail = current;
}
else
{
tail->next = current;
tail = current;
}
}
}
token = rdplus_response.token;
if (rdplus_response.pvfs_dirent_outcount)
{
free(rdplus_response.dirent_array);
rdplus_response.dirent_array = NULL;
free(rdplus_response.stat_err_array);
rdplus_response.stat_err_array = NULL;
for (i = 0; i < rdplus_response.pvfs_dirent_outcount; i++) {
if (rdplus_response.attr_array)
{
PVFS_util_release_sys_attr(&rdplus_response.attr_array[i]);
}
}
free(rdplus_response.attr_array);
rdplus_response.attr_array = NULL;
}
} while(rdplus_response.pvfs_dirent_outcount == pvfs_dirent_incount);
if (do_timing) {
end = Wtime();
printf("PVFS_sys_readdirplus took %g msecs
",
(end - begin));
}
if (rdplus_response.pvfs_dirent_outcount)
{
free(rdplus_response.dirent_array);
rdplus_response.dirent_array = NULL;
free(rdplus_response.stat_err_array);
rdplus_response.stat_err_array = NULL;
for (i = 0; i < rdplus_response.pvfs_dirent_outcount; i++) {
if (rdplus_response.attr_array)
{
PVFS_util_release_sys_attr(&rdplus_response.attr_array[i]);
}
}
free(rdplus_response.attr_array);
rdplus_response.attr_array = NULL;
}
if (opts->list_recursive)//
{
current = head;
while(current)
{
printf("
");
do_list(full_path,current->path,fs_id,opts,entry_buffer);
current = current->next;
free(head->path);
free(head);
head = current;
}
}
return 0;
}