-/* preconditions: reiserfs_read_super already executed, therefore
- * INFO block is valid
- * returns: 0 if error, nonzero iff we were able to find the file successfully
- * postconditions: on a nonzero return, INFO->fileinfo contains the info
- * of the file we were trying to look up, filepos is 0 and filemax is
- * the size of the file.
- */
-static int
-reiserfs_open_file( char *dirname )
-{
- struct reiserfs_de_head *de_head;
- char *rest, ch;
- __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
-
- char linkbuf[PATH_MAX]; /* buffer for following symbolic links */
- int link_count = 0;
- int mode;
-
- dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
- objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
-
- while ( 1 )
- {
-
- DEBUG_F( "dirname=%s\n", dirname );
-
- /* Search for the stat info first. */
- if ( !search_stat( dir_id, objectid ) )
- return 0;
-
-
- DEBUG_F( "sd_mode=0%o sd_size=%u\n",
- sd_mode((struct stat_data *) INFO->current_item ),
- sd_size(INFO->current_ih, INFO->current_item ));
-
-
- mode = sd_mode((struct stat_data *)INFO->current_item);
-
- /* If we've got a symbolic link, then chase it. */
- if ( S_ISLNK( mode ) )
- {
- int len = 0;
-
- if ( ++link_count > MAX_LINK_COUNT )
- {
- errnum = FILE_ERR_SYMLINK_LOOP;
- return 0;
- }
-
- /* Get the symlink size. */
- INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
-
- /* Find out how long our remaining name is. */
- while ( dirname[len] && !isspace( dirname[len] ) )
- len++;
-
- if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
- {
- errnum = FILE_ERR_LENGTH;
- return 0;
- }
-
- /* Copy the remaining name to the end of the symlink data. Note *
- * that DIRNAME and LINKBUF may overlap! */
- memmove( linkbuf + INFO->file->len, dirname, len + 1 );
-
- INFO->fileinfo.k_dir_id = dir_id;
- INFO->fileinfo.k_objectid = objectid;
- INFO->file->pos = 0;
- if ( !next_key()
- || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len )
- return 0;
-
-
- DEBUG_F( "symlink=%s\n", linkbuf );
-
-
- dirname = linkbuf;
- if ( *dirname == '/' )
- {
- /* It's an absolute link, so look it up in root. */
- dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
- objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
- }
- else
- {
- /* Relative, so look it up in our parent directory. */
- dir_id = parent_dir_id;
- objectid = parent_objectid;
- }
-
- /* Now lookup the new name. */
- continue;
- }
-
- /* if we have a real file (and we're not just printing *
- * possibilities), then this is where we want to exit */
-
- if ( !*dirname || isspace( *dirname ) )
- {
- if ( !S_ISREG( mode ) )
- {
- errnum = FILE_ERR_BAD_TYPE;
- return 0;
- }
-
- INFO->file->pos = 0;
- INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);
-
- INFO->fileinfo.k_dir_id = dir_id;
- INFO->fileinfo.k_objectid = objectid;
- return next_key();
- }
-
- /* continue with the file/directory name interpretation */
- while ( *dirname == '/' )
- dirname++;
- if ( !S_ISDIR( mode ) )
- {
- errnum = FILE_ERR_BAD_TYPE;
- return 0;
- }
- for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
- rest++ ) ;
- *rest = 0;
-
- while ( 1 )
- {
- char *name_end;
- int num_entries;
-
- if ( !next_key() )
- return 0;
-
- if ( INFO->current_ih->ih_key.k_objectid != objectid )
- break;
-
- name_end = INFO->current_item + ih_item_len(INFO->current_ih);
- de_head = ( struct reiserfs_de_head * ) INFO->current_item;
- num_entries = ih_entry_count(INFO->current_ih);
- while ( num_entries > 0 )
- {
- char *filename = INFO->current_item + deh_location(de_head);
- char tmp = *name_end;
-
- if( deh_state(de_head) & (1 << DEH_Visible))
- {
- int cmp;
-
- /* Directory names in ReiserFS are not null * terminated.
- * We write a temporary 0 behind it. * NOTE: that this
- * may overwrite the first block in * the tree cache.
- * That doesn't hurt as long as we * don't call next_key
- * () in between. */
- *name_end = 0;
- cmp = strcmp( dirname, filename );
- *name_end = tmp;
- if ( cmp == 0 )
- goto found;
- }
- /* The beginning of this name marks the end of the next name.
- */
- name_end = filename;
- de_head++;
- num_entries--;
- }
- }
-
- errnum = FILE_ERR_NOTFOUND;
- *rest = ch;
- return 0;
-
- found:
- *rest = ch;
- dirname = rest;
-
- parent_dir_id = dir_id;
- parent_objectid = objectid;
- dir_id = de_head->deh_dir_id; /* LE */
- objectid = de_head->deh_objectid; /* LE */
- }
+ if ( INFO->current_ih->ih_key.k_objectid != objectid )
+ break;
+
+ name_end = INFO->current_item + ih_item_len(INFO->current_ih);
+ de_head = ( struct reiserfs_de_head * ) INFO->current_item;
+ num_entries = ih_entry_count(INFO->current_ih);
+ while ( num_entries > 0 )
+ {
+ char *filename = INFO->current_item + deh_location(de_head);
+ char tmp = *name_end;
+
+ if( deh_state(de_head) & (1 << DEH_Visible))
+ {
+ int cmp;
+
+ /* Directory names in ReiserFS are not null * terminated.
+ * We write a temporary 0 behind it. * NOTE: that this
+ * may overwrite the first block in * the tree cache.
+ * That doesn't hurt as long as we * don't call next_key
+ * () in between. */
+ *name_end = 0;
+ cmp = strcmp( dirname, filename );
+ *name_end = tmp;
+ if ( cmp == 0 )
+ goto found;
+ }
+ /* The beginning of this name marks the end of the next name.
+ */
+ name_end = filename;
+ de_head++;
+ num_entries--;
+ }
+ }
+
+ errnum = FILE_ERR_NOTFOUND;
+ *rest = ch;
+ return 0;
+
+ found:
+ *rest = ch;
+ dirname = rest;
+
+ parent_dir_id = dir_id;
+ parent_objectid = objectid;
+ dir_id = de_head->deh_dir_id; /* LE */
+ objectid = de_head->deh_objectid; /* LE */
+ }