aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Aleaxander <Aleaxander@gmail.com>2009-05-15 06:14:04 +0800
committerLiu Aleaxander <Aleaxander@gmail.com>2009-05-15 06:14:04 +0800
commit9fda17a1dd4e44ae151ea28d1dce978e23570db2 (patch)
treeb18457c8b3bbe77bc9196c1158048caee4cf5872
parent5505ac940ddfa5d8579bbe6597016dddc3825b8d (diff)
downloaddevel-9fda17a1dd4e44ae151ea28d1dce978e23570db2.tar.gz
devel-9fda17a1dd4e44ae151ea28d1dce978e23570db2.tar.xz
devel-9fda17a1dd4e44ae151ea28d1dce978e23570db2.zip
well, finally, the searchdir() function becomes simpiler
-rw-r--r--extlinux.c123
1 files changed, 64 insertions, 59 deletions
diff --git a/extlinux.c b/extlinux.c
index ebffb05..62bd080 100644
--- a/extlinux.c
+++ b/extlinux.c
@@ -102,6 +102,11 @@ char trackbuf[TRACKBUFSIZE];
__u32 EndBlock;
+char SymlinkBuf[SYMLINK_SECTORS * SECTOR_SIZE + 64];
+char *SymlinkTmpBuf = trackbuf;
+char *lnk_end;
+char *SymlinkTmpBufEnd = trackbuf + SYMLINK_SECTORS * SECTOR_SIZE+64;
+
/**
* strecpy:
@@ -656,6 +661,48 @@ struct ext2_dir_entry* find_dir_entry(struct open_file_t *file, char *filename)
}
+char* do_symlink(struct open_file_t *file, __u32 file_len, char *filename)
+{
+ int flag, have_more;
+
+
+ flag = ThisInode.i_file_acl ? SecPerClust : 0;
+
+ if ( ThisInode.i_blocks == flag ) {
+ /* fast symlink */
+ close_file(file); /* we've got all we need */
+ memcpy(SymlinkTmpBuf, ThisInode.i_block, file_len);
+ lnk_end = SymlinkTmpBuf + file_len;
+
+ } else {
+ /* slow symlink */
+ getfssec(SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
+ lnk_end = SymlinkTmpBuf + file_len;
+ }
+
+ /*
+ * well, this happens like:
+ * "/boot/xxx/y/z.abc" where xxx is a symlink to "/other/here"
+ * so, we should get a new path name like:
+ * "/other/here/y/z.abc"
+ */
+ if ( *filename != 0 )
+ *lnk_end++ = '/';
+
+ if ( strecpy(lnk_end, filename, SymlinkTmpBufEnd) )
+ return NULL; /* buffer overflow */
+
+ /*
+ * now copy it to the "real" buffer; we need to have
+ * two buffers so we avoid overwriting the tail on
+ * the next copy.
+ */
+ strcpy(SymlinkBuf, SymlinkTmpBuf);
+
+ /* return the new path */
+ return SymlinkBuf;
+}
+
@@ -674,22 +721,10 @@ 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;
-
- __u32 have_more;
+ __u8 file_mode;
+ __u8 SymlinkCtr = MAX_SYMLINKS;
__u32 inr = CurrentDir;
__u32 ThisDir;
-
-
- int flag;
-
-
- char SymlinkBuf[SYMLINK_SECTORS * SECTOR_SIZE + 64];
- char *SymlinkTmpBuf = trackbuf;
- char *lnk_end;
- char *SymlinkTmpBufEnd = trackbuf + SYMLINK_SECTORS * SECTOR_SIZE+64;
-
begin_path:
@@ -714,8 +749,7 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
/* It's a directory */
- if ( file_mode == T_IFDIR ) {
-
+ if ( file_mode == T_IFDIR ) {
ThisDir = inr;
if ( *filename == 0 )
@@ -724,12 +758,13 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
filename ++;
de = find_dir_entry(file, filename);
- if (de) {
- inr = de->d_inode;
- filename += de->d_name_len;
- close(file);
- goto open;
- }
+ if ( !de )
+ return NULL;
+
+ inr = de->d_inode;
+ filename += de->d_name_len;
+ close(file);
+ goto open;
}
@@ -742,45 +777,15 @@ struct open_file_t* searchdir(char * filename, __u32 *file_len)
* if absolute, and append any remaining part of the path.
*/
if ( file_mode == T_IFLNK ) {
- if ( --SymlinkCtr == 0 ) /* too many links */
- goto err;
- if ( *file_len >= SYMLINK_SECTORS * SECTOR_SIZE )
- goto err; /* Symlink too long */
-
- flag = ThisInode.i_file_acl ? SecPerClust : 0;
-
- if ( ThisInode.i_blocks == flag ) { /* fast symlink */
-
- close_file(file); /* we've got all we need */
- memcpy(SymlinkTmpBuf, ThisInode.i_block, *file_len);
- lnk_end = SymlinkTmpBuf + *file_len;
-
- } else { /* slow symlink */
- getfssec(SymlinkTmpBuf,file,SYMLINK_SECTORS,&have_more);
- lnk_end = SymlinkTmpBuf + *file_len;
- }
-
- /*
- * well, this happens like:
- * "/boot/xxx/y/z.abc" where xxx is a symlink to "/other/here"
- * so, we should get a new name like:
- * "/other/here/y/z.abc"
- */
- if ( *filename != 0 )
- *lnk_end++ = '/';
-
- if ( strecpy(lnk_end, filename, SymlinkTmpBufEnd) )
- goto err_noclose; /* buffer overflow */
+ if ( --SymlinkCtr==0 || *file_len>=SYMLINK_SECTORS*SECTOR_SIZE)
+ goto err; /* too many links or symlink too long */
- /*
- * now copy it to the "real" buffer; we need to have
- * two buffers so we avoid overwriting the tail on
- * the next copy.
- */
- strcpy(SymlinkBuf, SymlinkTmpBuf);
+ filename = do_symlink(file, *file_len, filename);
+ if ( !filename )
+ goto err_noclose;/* buffer overflow */
+
inr = ThisDir;
- filename = SymlinkBuf;
- goto begin_path; /* we got a new path, so search it again */
+ goto begin_path; /* we got a new path, so search it again */
}
/* Otherwise, something bad ... */