string: factorize skip_spaces and export it to be generally available
[safe/jmp/linux-2.6] / fs / isofs / dir.c
index 0e94c31..8ba5441 100644 (file)
@@ -7,34 +7,18 @@
  *
  *  Steve Beynon                      : Missing last directory entries fixed
  *  (stephen@askone.demon.co.uk)      : 21st June 1996
- * 
+ *
  *  isofs directory handling functions
  */
 #include <linux/smp_lock.h>
 #include "isofs.h"
 
-static int isofs_readdir(struct file *, void *, filldir_t);
-
-const struct file_operations isofs_dir_operations =
-{
-       .read           = generic_read_dir,
-       .readdir        = isofs_readdir,
-};
-
-/*
- * directories can handle most operations...
- */
-const struct inode_operations isofs_dir_inode_operations =
-{
-       .lookup         = isofs_lookup,
-};
-
 int isofs_name_translate(struct iso_directory_record *de, char *new, struct inode *inode)
 {
        char * old = de->name;
        int len = de->name_len[0];
        int i;
-                       
+
        for (i = 0; i < len; i++) {
                unsigned char c = old[i];
                if (!c)
@@ -62,22 +46,27 @@ int isofs_name_translate(struct iso_directory_record *de, char *new, struct inod
 }
 
 /* Acorn extensions written by Matthew Wilcox <willy@bofh.ai> 1998 */
-int get_acorn_filename(struct iso_directory_record * de,
-                           char * retname, struct inode * inode)
+int get_acorn_filename(struct iso_directory_record *de,
+                           char *retname, struct inode *inode)
 {
        int std;
-       unsigned char * chr;
+       unsigned char *chr;
        int retnamlen = isofs_name_translate(de, retname, inode);
-       if (retnamlen == 0) return 0;
+
+       if (retnamlen == 0)
+               return 0;
        std = sizeof(struct iso_directory_record) + de->name_len[0];
-       if (std & 1) std++;
-       if ((*((unsigned char *) de) - std) != 32) return retnamlen;
+       if (std & 1)
+               std++;
+       if ((*((unsigned char *) de) - std) != 32)
+               return retnamlen;
        chr = ((unsigned char *) de) + std;
-       if (strncmp(chr, "ARCHIMEDES", 10)) return retnamlen;
-       if ((*retname == '_') && ((chr[19] & 1) == 1)) *retname = '!';
+       if (strncmp(chr, "ARCHIMEDES", 10))
+               return retnamlen;
+       if ((*retname == '_') && ((chr[19] & 1) == 1))
+               *retname = '!';
        if (((de->flags[0] & 2) == 0) && (chr[13] == 0xff)
-               && ((chr[12] & 0xf0) == 0xf0))
-       {
+               && ((chr[12] & 0xf0) == 0xf0)) {
                retname[retnamlen] = ',';
                sprintf(retname+retnamlen+1, "%3.3x",
                        ((chr[12] & 0xf) << 8) | chr[11]);
@@ -91,7 +80,7 @@ int get_acorn_filename(struct iso_directory_record * de,
  */
 static int do_isofs_readdir(struct inode *inode, struct file *filp,
                void *dirent, filldir_t filldir,
-               char * tmpname, struct iso_directory_record * tmpde)
+               char *tmpname, struct iso_directory_record *tmpde)
 {
        unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
        unsigned char bufbits = ISOFS_BUFFER_BITS(inode);
@@ -121,9 +110,11 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                de_len = *(unsigned char *) de;
 
-               /* If the length byte is zero, we should move on to the next
-                  CDROM sector.  If we are at the end of the directory, we
-                  kick out of the while loop. */
+               /*
+                * If the length byte is zero, we should move on to the next
+                * CDROM sector.  If we are at the end of the directory, we
+                * kick out of the while loop.
+                */
 
                if (de_len == 0) {
                        brelse(bh);
@@ -154,14 +145,21 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                        }
                        de = tmpde;
                }
+               /* Basic sanity check, whether name doesn't exceed dir entry */
+               if (de_len < de->name_len[0] +
+                                       sizeof(struct iso_directory_record)) {
+                       printk(KERN_NOTICE "iso9660: Corrupted directory entry"
+                              " in block %lu of inode %lu\n", block,
+                              inode->i_ino);
+                       return -EIO;
+               }
 
                if (first_de) {
                        isofs_normalize_block_and_offset(de,
-                                                        &block_saved,
-                                                        &offset_saved);
+                                                       &block_saved,
+                                                       &offset_saved);
                        inode_number = isofs_get_ino(block_saved,
-                                                    offset_saved,
-                                                    bufbits);
+                                                       offset_saved, bufbits);
                }
 
                if (de->flags[-sbi->s_high_sierra] & 0x80) {
@@ -197,9 +195,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
                 * Do not report hidden files if so instructed, or associated
                 * files unless instructed to do so
                 */
-               if ((sbi->s_hide == 'y' &&
-                               (de->flags[-sbi->s_high_sierra] & 1)) ||
-                     (sbi->s_showassoc =='n' &&
+               if ((sbi->s_hide && (de->flags[-sbi->s_high_sierra] & 1)) ||
+                   (!sbi->s_showassoc &&
                                (de->flags[-sbi->s_high_sierra] & 4))) {
                        filp->f_pos += de_len;
                        continue;
@@ -240,7 +237,8 @@ static int do_isofs_readdir(struct inode *inode, struct file *filp,
 
                continue;
        }
-       if (bh) brelse(bh);
+       if (bh)
+               brelse(bh);
        return 0;
 }
 
@@ -253,8 +251,8 @@ static int isofs_readdir(struct file *filp,
                void *dirent, filldir_t filldir)
 {
        int result;
-       char * tmpname;
-       struct iso_directory_record * tmpde;
+       char *tmpname;
+       struct iso_directory_record *tmpde;
        struct inode *inode = filp->f_path.dentry->d_inode;
 
        tmpname = (char *)__get_free_page(GFP_KERNEL);
@@ -270,3 +268,19 @@ static int isofs_readdir(struct file *filp,
        unlock_kernel();
        return result;
 }
+
+const struct file_operations isofs_dir_operations =
+{
+       .read = generic_read_dir,
+       .readdir = isofs_readdir,
+};
+
+/*
+ * directories can handle most operations...
+ */
+const struct inode_operations isofs_dir_inode_operations =
+{
+       .lookup = isofs_lookup,
+};
+
+