!C99Shell v. 1.0 pre-release build #13!

Software: Apache/2.0.54 (Unix) mod_perl/1.99_09 Perl/v5.8.0 mod_ssl/2.0.54 OpenSSL/0.9.7l DAV/2 FrontPage/5.0.2.2635 PHP/4.4.0 mod_gzip/2.0.26.1a 

uname -a: Linux snow.he.net 4.4.276-v2-mono-1 #1 SMP Wed Jul 21 11:21:17 PDT 2021 i686 

uid=99(nobody) gid=98(nobody) groups=98(nobody) 

Safe-mode: OFF (not secure)

/usr/src/linux-2.4.18-xfs-1.1/fs/hfs/   drwxr-xr-x
Free 318.34 GB of 458.09 GB (69.49%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     inode.c (15.47 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * linux/fs/hfs/inode.c
 *
 * Copyright (C) 1995-1997  Paul H. Hargrove
 * This file may be distributed under the terms of the GNU General Public License.
 *
 * This file contains inode-related functions which do not depend on
 * which scheme is being used to represent forks.
 *
 * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
 *
 * "XXX" in a comment is a note to myself to consider changing something.
 *
 * In function preconditions the term "valid" applied to a pointer to
 * a structure means that the pointer is non-NULL and the structure it
 * points to has all fields initialized to consistent values.
 */

#include "hfs.h"
#include <linux/hfs_fs_sb.h>
#include <linux/hfs_fs_i.h>
#include <linux/hfs_fs.h>
#include <linux/smp_lock.h>

/*================ Variable-like macros ================*/

#define HFS_VALID_MODE_BITS  (S_IFREG | S_IFDIR | S_IRWXUGO)

/*================ File-local functions ================*/

/*
 * init_file_inode()
 *
 * Given an HFS catalog entry initialize an inode for a file.
 */
static void init_file_inode(struct inode *inode, hfs_u8 fork)
{
    struct hfs_fork *fk;
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;

    if (fork == HFS_FK_DATA) {
        inode->i_mode = S_IRWXUGO | S_IFREG;
    } else {
        inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
    }

    if (fork == HFS_FK_DATA) {
#if 0 /* XXX: disable crlf translations for now */
        hfs_u32 type = hfs_get_nl(entry->info.file.finfo.fdType);

        HFS_I(inode)->convert =
            ((HFS_SB(inode->i_sb)->s_conv == 't') ||
             ((HFS_SB(inode->i_sb)->s_conv == 'a') &&
              ((type == htonl(0x54455854)) ||   /* "TEXT" */
               (type == htonl(0x7474726f)))));  /* "ttro" */
#else
        HFS_I(inode)->convert = 0;
#endif
        fk = &entry->u.file.data_fork;
    } else {
        fk = &entry->u.file.rsrc_fork;
        HFS_I(inode)->convert = 0;
    }
    HFS_I(inode)->fork = fk;
    inode->i_size = fk->lsize;
    inode->i_blocks = fk->psize;
    inode->i_nlink = 1;
}

/*================ Global functions ================*/

/*
 * hfs_put_inode()
 *
 * This is the put_inode() entry in the super_operations for HFS
 * filesystems.  The purpose is to perform any filesystem-dependent 
 * cleanup necessary when the use-count of an inode falls to zero.
 */
void hfs_put_inode(struct inode * inode)
{
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;

    lock_kernel();
    hfs_cat_put(entry);
    if (atomic_read(&inode->i_count) == 1) {
      struct hfs_hdr_layout *tmp = HFS_I(inode)->layout;

      if (tmp) {
        HFS_I(inode)->layout = NULL;
        HFS_DELETE(tmp);
      }
    }
    unlock_kernel();
}

/*
 * hfs_notify_change()
 *
 * Based very closely on fs/msdos/inode.c by Werner Almesberger
 *
 * This is the notify_change() field in the super_operations structure
 * for HFS file systems.  The purpose is to take that changes made to
 * an inode and apply then in a filesystem-dependent manner.  In this
 * case the process has a few of tasks to do:
 *  1) prevent changes to the i_uid and i_gid fields.
 *  2) map file permissions to the closest allowable permissions
 *  3) Since multiple Linux files can share the same on-disk inode under
 *     HFS (for instance the data and resource forks of a file) a change
 *     to permissions must be applied to all other in-core inodes which 
 *     correspond to the same HFS file.
 */
enum {HFS_NORM, HFS_HDR, HFS_CAP};

static int __hfs_notify_change(struct dentry *dentry, struct iattr * attr, int kind)
{
    struct inode *inode = dentry->d_inode;
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;
    struct dentry **de = entry->sys_entry;
    struct hfs_sb_info *hsb = HFS_SB(inode->i_sb);
    int error, i;

    error = inode_change_ok(inode, attr); /* basic permission checks */
    if (error) {
        /* Let netatalk's afpd think chmod() always succeeds */
        if (hsb->s_afpd &&
            (attr->ia_valid == (ATTR_MODE | ATTR_CTIME))) {
            return 0;
        } else {
            return error;
        }
    }

    /* no uig/gid changes and limit which mode bits can be set */
    if (((attr->ia_valid & ATTR_UID) && 
         (attr->ia_uid != hsb->s_uid)) ||
        ((attr->ia_valid & ATTR_GID) && 
         (attr->ia_gid != hsb->s_gid)) ||
        ((attr->ia_valid & ATTR_MODE) &&
         (((entry->type == HFS_CDR_DIR) &&
           (attr->ia_mode != inode->i_mode))||
          (attr->ia_mode & ~HFS_VALID_MODE_BITS)))) {
        return hsb->s_quiet ? 0 : error;
    }
    
    if (entry->type == HFS_CDR_DIR) {
        attr->ia_valid &= ~ATTR_MODE;
    } else if (attr->ia_valid & ATTR_MODE) {
        /* Only the 'w' bits can ever change and only all together. */
        if (attr->ia_mode & S_IWUSR) {
            attr->ia_mode = inode->i_mode | S_IWUGO;
        } else {
            attr->ia_mode = inode->i_mode & ~S_IWUGO;
        }
        attr->ia_mode &= ~hsb->s_umask;
    }
    /*
     * Normal files handle size change in normal way.
     * Oddballs are served here.
     */
    if (attr->ia_valid & ATTR_SIZE) {
        if (kind == HFS_CAP) {
            inode->i_size = attr->ia_size;
            if (inode->i_size > HFS_FORK_MAX)
                inode->i_size = HFS_FORK_MAX;
            mark_inode_dirty(inode);
            attr->ia_valid &= ~ATTR_SIZE;
        } else if (kind == HFS_HDR) {
            hdr_truncate(inode, attr->ia_size);
            attr->ia_valid &= ~ATTR_SIZE;
        }
    }
    error = inode_setattr(inode, attr);
    if (error)
        return error;

    /* We wouldn't want to mess with the sizes of the other fork */
    attr->ia_valid &= ~ATTR_SIZE;

    /* We must change all in-core inodes corresponding to this file. */
    for (i = 0; i < 4; ++i) {
      if (de[i] && (de[i] != dentry)) {
        inode_setattr(de[i]->d_inode, attr);
      }
    }

    /* Change the catalog entry if needed */
    if (attr->ia_valid & ATTR_MTIME) {
        entry->modify_date = hfs_u_to_mtime(inode->i_mtime);
        hfs_cat_mark_dirty(entry);
    }
    if (attr->ia_valid & ATTR_MODE) {
        hfs_u8 new_flags;

        if (inode->i_mode & S_IWUSR) {
            new_flags = entry->u.file.flags & ~HFS_FIL_LOCK;
        } else {
            new_flags = entry->u.file.flags | HFS_FIL_LOCK;
        }

        if (new_flags != entry->u.file.flags) {
            entry->u.file.flags = new_flags;
            hfs_cat_mark_dirty(entry);
        }
    }
    /* size changes handled in hfs_extent_adj() */

    return 0;
}

int hfs_notify_change(struct dentry *dentry, struct iattr * attr)
{
    return __hfs_notify_change(dentry, attr, HFS_NORM);
}

int hfs_notify_change_cap(struct dentry *dentry, struct iattr * attr)
{
    return __hfs_notify_change(dentry, attr, HFS_CAP);
}

int hfs_notify_change_hdr(struct dentry *dentry, struct iattr * attr)
{
    return __hfs_notify_change(dentry, attr, HFS_HDR);
}

static int hfs_writepage(struct page *page)
{
    return block_write_full_page(page,hfs_get_block);
}
static int hfs_readpage(struct file *file, struct page *page)
{
    return block_read_full_page(page,hfs_get_block);
}
static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
{
    return cont_prepare_write(page,from,to,hfs_get_block,
        &page->mapping->host->u.hfs_i.mmu_private);
}
static int hfs_bmap(struct address_space *mapping, long block)
{
    return generic_block_bmap(mapping,block,hfs_get_block);
}
struct address_space_operations hfs_aops = {
    readpage: hfs_readpage,
    writepage: hfs_writepage,
    sync_page: block_sync_page,
    prepare_write: hfs_prepare_write,
    commit_write: generic_commit_write,
    bmap: hfs_bmap
};

/*
 * __hfs_iget()
 *
 * Given the MDB for a HFS filesystem, a 'key' and an 'entry' in
 * the catalog B-tree and the 'type' of the desired file return the
 * inode for that file/directory or NULL.  Note that 'type' indicates
 * whether we want the actual file or directory, or the corresponding
 * metadata (AppleDouble header file or CAP metadata file).
 *
 * In an ideal world we could call iget() and would not need this
 * function.  However, since there is no way to even know the inode
 * number until we've found the file/directory in the catalog B-tree
 * that simply won't happen.
 *
 * The main idea here is to look in the catalog B-tree to get the
 * vital info about the file or directory (including the file id which
 * becomes the inode number) and then to call iget() and return the
 * inode if it is complete.  If it is not then we use the catalog
 * entry to fill in the missing info, by calling the appropriate
 * 'fillin' function.  Note that these fillin functions are
 * essentially hfs_*_read_inode() functions, but since there is no way
 * to pass the catalog entry through iget() to such a read_inode()
 * function, we have to call them after iget() returns an incomplete
 * inode to us.     This is pretty much the same problem faced in the NFS
 * code, and pretty much the same solution. The SMB filesystem deals
 * with this in a different way: by using the address of the
 * kmalloc()'d space which holds the data as the inode number.
 *
 * XXX: Both this function and NFS's corresponding nfs_fhget() would
 * benefit from a way to pass an additional (void *) through iget() to
 * the VFS read_inode() function.
 *
 * this will hfs_cat_put() the entry if it fails.
 */
struct inode *hfs_iget(struct hfs_cat_entry *entry, ino_t type,
               struct dentry *dentry)
{
    struct dentry **sys_entry;
    struct super_block *sb;
    struct inode *inode;

    if (!entry) {
        return NULL;
    }

    /* If there are several processes all calling __iget() for
       the same inode then they will all get the same one back.
       The first one to return from __iget() will notice that the
       i_mode field of the inode is blank and KNOW that it is
       the first to return.  Therefore, it will set the appropriate
       'sys_entry' field in the entry and initialize the inode.
       All the initialization must be done without sleeping,
       or else other processes could end up using a partially
       initialized inode.                */

    sb = entry->mdb->sys_mdb;
    sys_entry = &entry->sys_entry[HFS_ITYPE_TO_INT(type)];

    if (!(inode = iget(sb, ntohl(entry->cnid) | type))) {
            hfs_cat_put(entry);
            return NULL;
    }

    if (inode->i_dev != sb->s_dev) {
            iput(inode); /* automatically does an hfs_cat_put */
        inode = NULL;
    } else if (!inode->i_mode || (*sys_entry == NULL)) {
        /* Initialize the inode */
        struct hfs_sb_info *hsb = HFS_SB(sb);

        inode->i_rdev = 0;
        inode->i_ctime = inode->i_atime = inode->i_mtime =
                    hfs_m_to_utime(entry->modify_date);
        inode->i_blksize = HFS_SECTOR_SIZE;
        inode->i_uid = hsb->s_uid;
        inode->i_gid = hsb->s_gid;

        memset(HFS_I(inode), 0, sizeof(struct hfs_inode_info));
        HFS_I(inode)->magic = HFS_INO_MAGIC;
        HFS_I(inode)->entry = entry;
        HFS_I(inode)->tz_secondswest = hfs_to_utc(0);

        hsb->s_ifill(inode, type, hsb->s_version);
        if (!hsb->s_afpd && (entry->type == HFS_CDR_FIL) &&
            (entry->u.file.flags & HFS_FIL_LOCK)) {
            inode->i_mode &= ~S_IWUGO;
        }
        inode->i_mode &= ~hsb->s_umask;

        if (!inode->i_mode) {
            iput(inode); /* does an hfs_cat_put */
            inode = NULL;
        } else
            *sys_entry = dentry; /* cache dentry */

    }

    return inode;
}

/*================ Scheme-specific functions ================*/

/* 
 * hfs_cap_ifill()
 *
 * This function serves the same purpose as a read_inode() function does
 * in other filesystems.  It is called by __hfs_iget() to fill in
 * the missing fields of an uninitialized inode under the CAP scheme.
 */
void hfs_cap_ifill(struct inode * inode, ino_t type, const int version)
{
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;

    HFS_I(inode)->d_drop_op = hfs_cap_drop_dentry;
    if (type == HFS_CAP_FNDR) {
        inode->i_size = sizeof(struct hfs_cap_info);
        inode->i_blocks = 0;
        inode->i_nlink = 1;
        inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
        inode->i_op = &hfs_cap_info_inode_operations;
        inode->i_fop = &hfs_cap_info_operations;
    } else if (entry->type == HFS_CDR_FIL) {
        init_file_inode(inode, (type == HFS_CAP_DATA) ?
                        HFS_FK_DATA : HFS_FK_RSRC);
        inode->i_op = &hfs_file_inode_operations;
        inode->i_fop = &hfs_file_operations;
        inode->i_mapping->a_ops = &hfs_aops;
        inode->u.hfs_i.mmu_private = inode->i_size;
    } else { /* Directory */
        struct hfs_dir *hdir = &entry->u.dir;

        inode->i_blocks = 0;
        inode->i_size = hdir->files + hdir->dirs + 5;
        HFS_I(inode)->dir_size = 1;
        if (type == HFS_CAP_NDIR) {
            inode->i_mode = S_IRWXUGO | S_IFDIR;
            inode->i_nlink = hdir->dirs + 4;
            inode->i_op = &hfs_cap_ndir_inode_operations;
            inode->i_fop = &hfs_cap_dir_operations;
            HFS_I(inode)->file_type = HFS_CAP_NORM;
        } else if (type == HFS_CAP_FDIR) {
            inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
            inode->i_nlink = 2;
            inode->i_op = &hfs_cap_fdir_inode_operations;
            inode->i_fop = &hfs_cap_dir_operations;
            HFS_I(inode)->file_type = HFS_CAP_FNDR;
        } else if (type == HFS_CAP_RDIR) {
            inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
            inode->i_nlink = 2;
            inode->i_op = &hfs_cap_rdir_inode_operations;
            inode->i_fop = &hfs_cap_dir_operations;
            HFS_I(inode)->file_type = HFS_CAP_RSRC;
        }
    }
}

/* 
 * hfs_dbl_ifill()
 *
 * This function serves the same purpose as a read_inode() function does
 * in other filesystems.  It is called by __hfs_iget() to fill in
 * the missing fields of an uninitialized inode under the AppleDouble
 * scheme.
 */
void hfs_dbl_ifill(struct inode * inode, ino_t type, const int version)
{
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;

    HFS_I(inode)->d_drop_op = hfs_dbl_drop_dentry;
    if (type == HFS_DBL_HDR) {
        if (entry->type == HFS_CDR_FIL) {
            init_file_inode(inode, HFS_FK_RSRC);
            inode->i_size += HFS_DBL_HDR_LEN;
            HFS_I(inode)->default_layout = &hfs_dbl_fil_hdr_layout;
        } else {
            inode->i_size = HFS_DBL_HDR_LEN;
            inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
            inode->i_nlink = 1;
            HFS_I(inode)->default_layout = &hfs_dbl_dir_hdr_layout;
        }
        inode->i_op = &hfs_hdr_inode_operations;
        inode->i_fop = &hfs_hdr_operations;
    } else if (entry->type == HFS_CDR_FIL) {
        init_file_inode(inode, HFS_FK_DATA);
        inode->i_op = &hfs_file_inode_operations;
        inode->i_fop = &hfs_file_operations;
        inode->i_mapping->a_ops = &hfs_aops;
        inode->u.hfs_i.mmu_private = inode->i_size;
    } else { /* Directory */
        struct hfs_dir *hdir = &entry->u.dir;

        inode->i_blocks = 0;
        inode->i_nlink = hdir->dirs + 2;
        inode->i_size = 3 + 2 * (hdir->dirs + hdir->files);
        inode->i_mode = S_IRWXUGO | S_IFDIR;
        inode->i_op = &hfs_dbl_dir_inode_operations;
        inode->i_fop = &hfs_dbl_dir_operations;
        HFS_I(inode)->file_type = HFS_DBL_NORM;
        HFS_I(inode)->dir_size = 2;
    }
}

/* 
 * hfs_nat_ifill()
 *
 * This function serves the same purpose as a read_inode() function does
 * in other filesystems.  It is called by __hfs_iget() to fill in
 * the missing fields of an uninitialized inode under the Netatalk
 * scheme.
 */
void hfs_nat_ifill(struct inode * inode, ino_t type, const int version)
{
    struct hfs_cat_entry *entry = HFS_I(inode)->entry;

    HFS_I(inode)->d_drop_op = hfs_nat_drop_dentry;
    if (type == HFS_NAT_HDR) {
        if (entry->type == HFS_CDR_FIL) {
            init_file_inode(inode, HFS_FK_RSRC);
            inode->i_size += HFS_NAT_HDR_LEN;
        } else {
            inode->i_size = HFS_NAT_HDR_LEN;
            inode->i_mode = S_IRUGO | S_IWUGO | S_IFREG;
            inode->i_nlink = 1;
        }
        inode->i_op = &hfs_hdr_inode_operations;
        inode->i_fop = &hfs_hdr_operations;
        HFS_I(inode)->default_layout = (version == 2) ?
            &hfs_nat2_hdr_layout : &hfs_nat_hdr_layout;
    } else if (entry->type == HFS_CDR_FIL) {
        init_file_inode(inode, HFS_FK_DATA);
        inode->i_op = &hfs_file_inode_operations;
        inode->i_fop = &hfs_file_operations;
        inode->i_mapping->a_ops = &hfs_aops;
        inode->u.hfs_i.mmu_private = inode->i_size;
    } else { /* Directory */
        struct hfs_dir *hdir = &entry->u.dir;

        inode->i_blocks = 0;
        inode->i_size = hdir->files + hdir->dirs + 4;
        inode->i_mode = S_IRWXUGO | S_IFDIR;
        HFS_I(inode)->dir_size = 1;
        if (type == HFS_NAT_NDIR) {
            inode->i_nlink = hdir->dirs + 3;
            inode->i_op = &hfs_nat_ndir_inode_operations;
            HFS_I(inode)->file_type = HFS_NAT_NORM;
        } else if (type == HFS_NAT_HDIR) {
            inode->i_nlink = 2;
            inode->i_op = &hfs_nat_hdir_inode_operations;
            HFS_I(inode)->file_type = HFS_NAT_HDR;
        }
        inode->i_fop = &hfs_nat_dir_operations;
    }
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 1.0 pre-release build #13 powered by Captain Crunch Security Team | http://ccteam.ru | Generation time: 0.0329 ]--