!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:     dir.c (10.45 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * linux/fs/hfs/dir.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 directory-related functions independent of 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>

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

/*
 * build_key()
 *
 * Build a key for a file by the given name in the given directory.
 * If the name matches one of the reserved names returns 1 otherwise 0.
 */
static int build_key(struct hfs_cat_key *key, struct inode *dir,
             const char *name, int len)
{
    struct hfs_name cname;
    const struct hfs_name *reserved;

    /* mangle the name */
    hfs_nameout(dir, &cname, name, len);

    /* check against reserved names */
    reserved = HFS_SB(dir->i_sb)->s_reserved1;
    while (reserved->Len) {
        if (hfs_streq(reserved->Name, reserved->Len, 
                  cname.Name, cname.Len)) {
            return 1;
        }
        ++reserved;
    }

    /* check against the names reserved only in the root directory */
    if (HFS_I(dir)->entry->cnid == htonl(HFS_ROOT_CNID)) {
        reserved = HFS_SB(dir->i_sb)->s_reserved2;
        while (reserved->Len) {
            if (hfs_streq(reserved->Name, reserved->Len,
                      cname.Name, cname.Len)) {
                return 1;
            }
            ++reserved;
        }
    }

    /* build the key */
    hfs_cat_build_key(HFS_I(dir)->entry->cnid, &cname, key);

    return 0;
}

/*
 * update_dirs_plus()
 *
 * Update the fields 'i_size', 'i_nlink', 'i_ctime', 'i_mtime' and
 * 'i_version' of the inodes associated with a directory that has
 * had a file ('is_dir'==0) or directory ('is_dir'!=0) added to it.
 */
static inline void update_dirs_plus(struct hfs_cat_entry *dir, int is_dir)
{
    int i;

    for (i = 0; i < 4; ++i) {
        struct dentry *de = dir->sys_entry[i];
        if (de) {
                struct inode *tmp = de->d_inode;
            if (S_ISDIR(tmp->i_mode)) {
                if (is_dir &&
                    (i == HFS_ITYPE_TO_INT(HFS_ITYPE_NORM))) {
                    /* In "normal" directory only */
                    ++(tmp->i_nlink);
                }
                tmp->i_size += HFS_I(tmp)->dir_size;
                tmp->i_version = ++event;
            }
            tmp->i_ctime = tmp->i_mtime = CURRENT_TIME;
            mark_inode_dirty(tmp);
        }
    }
}

/*
 * update_dirs_minus()
 *
 * Update the fields 'i_size', 'i_nlink', 'i_ctime', 'i_mtime' and
 * 'i_version' of the inodes associated with a directory that has
 * had a file ('is_dir'==0) or directory ('is_dir'!=0) removed.
 */
static inline void update_dirs_minus(struct hfs_cat_entry *dir, int is_dir)
{
    int i;

    for (i = 0; i < 4; ++i) {
        struct dentry *de = dir->sys_entry[i];
        if (de) {
                struct inode *tmp = de->d_inode;
            if (S_ISDIR(tmp->i_mode)) {
                if (is_dir &&
                    (i == HFS_ITYPE_TO_INT(HFS_ITYPE_NORM))) {
                    /* In "normal" directory only */
                    --(tmp->i_nlink);
                }
                tmp->i_size -= HFS_I(tmp)->dir_size;
                tmp->i_version = ++event;
            }
            tmp->i_ctime = tmp->i_mtime = CURRENT_TIME;
            mark_inode_dirty(tmp);
        }
    }
}

/*
 * mark_inodes_deleted()
 *
 * Update inodes associated with a deleted entry to reflect its deletion.
 * Well, we really just drop the dentry.
 *
 * XXX: we should be using delete_inode for some of this stuff.
 */
static inline void mark_inodes_deleted(struct hfs_cat_entry *entry, 
                       struct dentry *dentry)
{
    struct dentry *de;
    struct inode *tmp;
    int i;

    for (i = 0; i < 4; ++i) {
        if ((de = entry->sys_entry[i]) && (dentry != de)) {
              dget(de);
              tmp = de->d_inode;
              tmp->i_nlink = 0;
              tmp->i_ctime = CURRENT_TIME;
              mark_inode_dirty(tmp);
              d_delete(de);
              dput(de);
        }
    }
}

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

/*
 * hfs_create()
 *
 * This is the create() entry in the inode_operations structure for
 * regular HFS directories.  The purpose is to create a new file in
 * a directory and return a corresponding inode, given the inode for
 * the directory and the name (and its length) of the new file.
 */
int hfs_create(struct inode * dir, struct dentry *dentry, int mode)
{
    struct hfs_cat_entry *entry = HFS_I(dir)->entry;
    struct hfs_cat_entry *new;
    struct hfs_cat_key key;
    struct inode *inode;
    int error;

    /* build the key, checking against reserved names */
    if (build_key(&key, dir, dentry->d_name.name, dentry->d_name.len)) 
        return -EEXIST;

    if ((error = hfs_cat_create(entry, &key, 
                   (mode & S_IWUSR) ? 0 : HFS_FIL_LOCK,
                   HFS_SB(dir->i_sb)->s_type,
                   HFS_SB(dir->i_sb)->s_creator, &new)))
        return error;

    /* create an inode for the new file. back out if we run
     * into trouble. */
    new->count++; /* hfs_iget() eats one */
    if (!(inode = hfs_iget(new, HFS_I(dir)->file_type, dentry))) {
        hfs_cat_delete(entry, new, 1);
        hfs_cat_put(new);
        return -EIO;
    }

    hfs_cat_put(new);
    update_dirs_plus(entry, 0);
    /* toss any relevant negative dentries */
    if (HFS_I(dir)->d_drop_op)
        HFS_I(dir)->d_drop_op(dentry, HFS_I(dir)->file_type);
    mark_inode_dirty(inode);
    d_instantiate(dentry, inode);
    return 0;
}

/*
 * hfs_mkdir()
 *
 * This is the mkdir() entry in the inode_operations structure for
 * regular HFS directories.  The purpose is to create a new directory
 * in a directory, given the inode for the parent directory and the
 * name (and its length) of the new directory.
 */
int hfs_mkdir(struct inode * parent, struct dentry *dentry, int mode)
{
    struct hfs_cat_entry *entry = HFS_I(parent)->entry;
    struct hfs_cat_entry *new;
    struct hfs_cat_key key;
    struct inode *inode;
    int error;

    /* build the key, checking against reserved names */
    if (build_key(&key, parent, dentry->d_name.name, 
              dentry->d_name.len)) 
        return -EEXIST;

    /* try to create the directory */
    if ((error = hfs_cat_mkdir(entry, &key, &new)))
        return error;

    /* back out if we run into trouble */
    new->count++; /* hfs_iget eats one */
    if (!(inode = hfs_iget(new, HFS_I(parent)->file_type, dentry))) {
        hfs_cat_delete(entry, new, 1);
        hfs_cat_put(new);
        return -EIO;
    }

    hfs_cat_put(new);
    update_dirs_plus(entry, 1);
    mark_inode_dirty(inode);
    d_instantiate(dentry, inode);
    return 0;
}

/*
 * hfs_unlink()
 *
 * This is the unlink() entry in the inode_operations structure for
 * regular HFS directories.  The purpose is to delete an existing
 * file, given the inode for the parent directory and the name
 * (and its length) of the existing file.
 */
int hfs_unlink(struct inode * dir, struct dentry *dentry)
{
    struct hfs_cat_entry *entry = HFS_I(dir)->entry;
    struct hfs_cat_entry *victim = NULL;
    struct hfs_cat_key key;
    int error;

    if (build_key(&key, dir, dentry->d_name.name,
              dentry->d_name.len)) 
        return -EPERM;

    if (!(victim = hfs_cat_get(entry->mdb, &key))) 
        return -ENOENT;

    error = -EPERM;
    if (victim->type != HFS_CDR_FIL)
        goto hfs_unlink_put;

    if (!(error = hfs_cat_delete(entry, victim, 1))) {
        struct inode *inode = dentry->d_inode;

        mark_inodes_deleted(victim, dentry);
        inode->i_nlink--; 
        inode->i_ctime = CURRENT_TIME;
        mark_inode_dirty(inode);
        update_dirs_minus(entry, 0);
    }

hfs_unlink_put:
    hfs_cat_put(victim);    /* Note that hfs_cat_put(NULL) is safe. */
    return error;
}

/*
 * hfs_rmdir()
 *
 * This is the rmdir() entry in the inode_operations structure for
 * regular HFS directories.  The purpose is to delete an existing
 * directory, given the inode for the parent directory and the name
 * (and its length) of the existing directory.
 */
int hfs_rmdir(struct inode * parent, struct dentry *dentry)
{
    struct hfs_cat_entry *entry = HFS_I(parent)->entry;
    struct hfs_cat_entry *victim = NULL;
    struct inode *inode = dentry->d_inode;
    struct hfs_cat_key key;
    int error;

    if (build_key(&key, parent, dentry->d_name.name,
              dentry->d_name.len))
        return -EPERM;

    if (!(victim = hfs_cat_get(entry->mdb, &key)))
        return -ENOENT;

    error = -ENOTDIR;
    if (victim->type != HFS_CDR_DIR) 
        goto hfs_rmdir_put;

    error = -EBUSY;
    if (!d_unhashed(dentry))
        goto hfs_rmdir_put;

    /* we only have to worry about 2 and 3 for mount points */
    if (victim->sys_entry[2] && d_mountpoint(victim->sys_entry[2]))
        goto hfs_rmdir_put;
    if (victim->sys_entry[3] && d_mountpoint(victim->sys_entry[3])) 
        goto hfs_rmdir_put;

    
    if ((error = hfs_cat_delete(entry, victim, 1)))
        goto hfs_rmdir_put;

    mark_inodes_deleted(victim, dentry);
    inode->i_nlink = 0;
    inode->i_ctime = CURRENT_TIME;
    mark_inode_dirty(inode);
    update_dirs_minus(entry, 1);
     
hfs_rmdir_put:
    hfs_cat_put(victim);    /* Note that hfs_cat_put(NULL) is safe. */
    return error;
}

/*
 * hfs_rename()
 *
 * This is the rename() entry in the inode_operations structure for
 * regular HFS directories.  The purpose is to rename an existing
 * file or directory, given the inode for the current directory and
 * the name (and its length) of the existing file/directory and the
 * inode for the new directory and the name (and its length) of the
 * new file/directory.
 * XXX: how do you handle must_be dir?
 */
int hfs_rename(struct inode *old_dir, struct dentry *old_dentry,
           struct inode *new_dir, struct dentry *new_dentry)
{
    struct hfs_cat_entry *old_parent = HFS_I(old_dir)->entry;
    struct hfs_cat_entry *new_parent = HFS_I(new_dir)->entry;
    struct hfs_cat_entry *victim = NULL;
    struct hfs_cat_entry *deleted;
    struct hfs_cat_key key;
    int error;

    if (build_key(&key, old_dir, old_dentry->d_name.name,
              old_dentry->d_name.len) ||
        (HFS_ITYPE(old_dir->i_ino) != HFS_ITYPE(new_dir->i_ino))) 
        return -EPERM;

    if (!(victim = hfs_cat_get(old_parent->mdb, &key))) 
        return -ENOENT;

    error = -EPERM;
    if (build_key(&key, new_dir, new_dentry->d_name.name,
                 new_dentry->d_name.len)) 
        goto hfs_rename_put;

    if (!(error = hfs_cat_move(old_parent, new_parent,
                   victim, &key, &deleted))) {
        int is_dir = (victim->type == HFS_CDR_DIR);
        
        /* drop the old dentries */
        mark_inodes_deleted(victim, old_dentry);
        update_dirs_minus(old_parent, is_dir);
        if (deleted) {
            mark_inodes_deleted(deleted, new_dentry);
            hfs_cat_put(deleted);
        } else {
            /* no existing inodes. just drop negative dentries */
            if (HFS_I(new_dir)->d_drop_op) 
                HFS_I(new_dir)->d_drop_op(new_dentry, 
                      HFS_I(new_dir)->file_type);
            update_dirs_plus(new_parent, is_dir);
        }
    
    }

hfs_rename_put:
    hfs_cat_put(victim);    /* Note that hfs_cat_put(NULL) is safe. */
    return error;
}

:: 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.0051 ]--