aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-05-15 05:39:03 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-05-15 05:39:03 +0800
commitd9441b88b3ad84535f4c2567955a0892f90d38c2 (patch)
treee191e311b6fbeea4e0a958b7407f401c62ba0a44
parent695fe3e49e318ec8c708c304c3c6bd5b6c868cb4 (diff)
downloaddevel-d9441b88b3ad84535f4c2567955a0892f90d38c2.tar.gz
devel-d9441b88b3ad84535f4c2567955a0892f90d38c2.tar.xz
devel-d9441b88b3ad84535f4c2567955a0892f90d38c2.zip
break out a find_dir_entry() from seachdir() big function
-rw-r--r--extlinux.c117
1 files changed, 67 insertions, 50 deletions
diff --git a/extlinux.c b/extlinux.c
index 1deedd0..572544f 100644
--- a/extlinux.c
+++ b/extlinux.c
@@ -97,6 +97,11 @@ __u32 CurrentDir = 13;
int blk_size;
+#define TRACKBUFSIZE 8192
+char trackbuf[TRACKBUFSIZE];
+__u32 EndBlock;
+
+
/**
* strecpy:
@@ -242,7 +247,7 @@ struct ext2_group_desc *get_group_desc(__u32 group_num)
* @param: inode_offset, the inode offset within a group;
* @prarm: dst, wher we will store the inode structure;
* @param: desc, the pointer to the group's descriptor
- * @param: block, a pointer, used for retruning the block number for file structure
+ * @param: block, a pointer used for retruning the blk number for file structure
* @param: offset, same as block
*
*/
@@ -607,6 +612,53 @@ int getfssec(char *buf, struct open_file_t *file, int sectors, int *have_more)
+/**
+ * find_dir_entry:
+ *
+ * find a dir entry, if find it return it or return NULL
+ *
+ */
+struct ext2_dir_entry* find_dir_entry(struct open_file_t *file, char *filename)
+{
+ int have_more;
+ struct ext2_dir_entry *de;
+
+
+ EndBlock = (__u32 )trackbuf + (SecPerClust << SECTOR_SHIFT);
+
+ /* read a clust at a time */
+ getfssec(trackbuf, file, SecPerClust, &have_more);
+ de = (struct ext2_dir_entry *)trackbuf;
+
+ while ( 1 ) {
+ if ( (char *)de >= (char *)EndBlock ) {
+ if (have_more) {
+ getfssec(trackbuf, file,SecPerClust,&have_more);
+ de = (struct ext2_dir_entry *)trackbuf;
+ } else
+ return NULL;
+ }
+
+ /* Zero inode == void entry */
+ if ( de->d_inode == 0 ) {
+ de = ext2_next_entry(de);
+ continue;
+ }
+
+ if ( ext2_match_entry (filename, de) ) {
+ filename += de->d_name_len;
+ if ( (*filename == 0) || (*filename == '/') )
+ return de; /* got it */
+
+ /* not match, restore the filename then try next */
+ filename -= de->d_name_len;
+ }
+
+ de = ext2_next_entry(de);
+ }
+}
+
+
@@ -626,17 +678,15 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
struct open_file_t *file;
struct ext2_dir_entry *de;
__u8 file_mode;
- __u8 SymlinkCtr = MAX_SYMLINKS;
-
+ __u8 SymlinkCtr = MAX_SYMLINKS;
__u32 have_more;
__u32 inr = CurrentDir;
__u32 ThisDir;
- __u32 EndBlock;
+
int flag;
- int trackbufsize = 8192;
- char trackbuf[trackbufsize];
+
char SymlinkBuf[SYMLINK_SECTORS * SECTOR_SIZE + 64];
char *SymlinkTmpBuf = trackbuf;
@@ -652,7 +702,7 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
}
open:
if ( (file = open_inode(inr, file_len) ) == NULL )
- goto done; /* if error, done */
+ return NULL;
file_mode = file->file_mode >> S_IFSHIFT;
@@ -676,49 +726,16 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
while ( *filename == '/' )
filename ++;
- EndBlock = (__u32 )trackbuf + (SecPerClust << SECTOR_SHIFT);
- readdir:
- /* read a clust at a time */
- getfssec(trackbuf, file, SecPerClust, &have_more);
-
-
- de = (struct ext2_dir_entry *)trackbuf;
-
- getent:
- while ( 1 ) {
- if ( (char *)de >= (char *)EndBlock ) {
- if (have_more)
- goto readdir;
- else
- goto err;
- }
-
- /* Zero inode == void entry */
- if ( de->d_inode == 0 ) {
- de = ext2_next_entry(de);
- continue;
- }
-
- if ( ext2_match_entry (filename, de) ) {
- inr = de->d_inode;
- filename += de->d_name_len;
- if ( *filename == 0 )
- goto finish;
- if ( *filename != '/' ) {
- /* not match, try next */
- de = ext2_next_entry(de);
- filename -= de->d_name_len;
- continue;
- }
- finish:
- close_file(file);
- goto open;
- }
-
- de = ext2_next_entry(de);
- }
+ de = find_dir_entry(file, filename);
+ if (de) {
+ inr = de->d_inode;
+ filename += de->d_name_len;
+ close(file);
+ goto open;
+ }
}
+
/*
* It's a symlink. We have to determine if it's a fast symlink
@@ -745,7 +762,7 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
getfssec(SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
lnk_end = SymlinkTmpBuf + *file_len;
}
- symlink_finish:
+
/*
* well, this happens like:
* "/boot/xxx/y/z.abc" where xxx is a symlink to "/other/here"
@@ -754,7 +771,7 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
*/
if ( *filename != 0 )
*lnk_end++ = '/';
- no_slash:
+
if ( strecpy(lnk_end, filename, SymlinkTmpBufEnd) )
goto err_noclose; /* buffer overflow */