diff options
Diffstat (limited to 'util.c')
-rw-r--r-- | util.c | 320 |
1 files changed, 320 insertions, 0 deletions
@@ -0,0 +1,320 @@ +/* $Header: /home/ksheff/src/e2tools/RCS/util.c,v 0.4 2002/06/05 20:38:16 ksheff Exp $ */ +/* + * util.c + * + * Copyright (C) 2002 Keith W Sheffield. This file may be redistributed + * under the terms of the GNU Public License. + * + * Derived from debugfs.c Copyright (C) 1993 Theodore Ts'o <tytso@mit.edu> + * and modified by Robert Sanders <gt8134b@prism.gatech.edu> + */ + +#ifndef UTIL_C +#define UTIL_C +#endif + +/* Description */ +/* + * Misc. utility functions + * + */ +/* + * $Log: util.c,v $ + * Revision 0.4 2002/06/05 20:38:16 ksheff + * Added regular expression routines. + * + * Revision 0.3 2002/04/10 09:31:21 ksheff + * Added function init_stat_buf(). + * + * Revision 0.2 2002/03/07 07:27:45 ksheff + * checked for return of ext2fs_unlink in rm_file(). + * + * Revision 0.1 2002/02/27 04:49:11 ksheff + * initial revision + * + */ + +/* Headers */ +#include "e2tools.h" +#include <regex.h> + +/* Macros */ + +/* Structures and Unions */ +typedef struct +{ + __u16 lmask; + mode_t mask; +} MODE_XLAT_T; + +static MODE_XLAT_T xlat_tbl[] = +{ + { LINUX_S_IFREG, S_IFREG }, + { LINUX_S_IFDIR, S_IFDIR }, + { LINUX_S_IFCHR, S_IFCHR }, + { LINUX_S_IFIFO, S_IFIFO }, + { LINUX_S_ISUID, S_ISUID }, + { LINUX_S_ISGID, S_ISGID }, + { LINUX_S_ISVTX, S_ISVTX }, + { LINUX_S_IRUSR, S_IRUSR }, + { LINUX_S_IWUSR, S_IWUSR }, + { LINUX_S_IXUSR, S_IXUSR }, + { LINUX_S_IRGRP, S_IRGRP }, + { LINUX_S_IWGRP, S_IWGRP }, + { LINUX_S_IXGRP, S_IXGRP }, + { LINUX_S_IROTH, S_IROTH }, + { LINUX_S_IWOTH, S_IWOTH }, + { LINUX_S_IXOTH, S_IXOTH }, + { 0, 0 } +}; + +/* External Variables */ + +/* Global Variables */ + +/* Local Variables */ + +/* External Prototypes */ + +/* Local Prototypes */ + +mode_t +ext2_mode_xlate(__u16 lmode); +__u16 +host_mode_xlate(mode_t hmode); +static int +release_blocks_proc(ext2_filsys fs, blk_t *blocknr, + int blockcnt, void *private); +long +delete_file(ext2_filsys fs, ext2_ino_t inode); + +/* translate a ext2 mode to the host OS representation */ +mode_t ext2_mode_xlate(__u16 lmode) +{ + mode_t mode = 0; + int i; + + for (i=0; xlat_tbl[i].lmask; i++) + { + if (lmode & xlat_tbl[i].lmask) + mode |= xlat_tbl[i].mask; + } + return mode; +} + +/* translate a host OS mode to the ext2 representation */ +__u16 host_mode_xlate(mode_t hmode) +{ + __u16 mode = 0; + int i; + + for (i=0; xlat_tbl[i].lmask; i++) + { + if (hmode & xlat_tbl[i].mask) + mode |= xlat_tbl[i].lmask; + } + return mode; +} + +long +open_filesystem(char *name, ext2_filsys *fs, ext2_ino_t *root, int rw_mode) +{ + int retval; + int closeval; + + + if ((retval = ext2fs_open(name, (rw_mode) ? EXT2_FLAG_RW : 0, 0, 0, + unix_io_manager, fs))) + { + fprintf(stderr, "%s\n", error_message(retval)); + *fs = NULL; + return retval; + } + + if ((retval = ext2fs_read_inode_bitmap(*fs))) + { + fprintf(stderr, "%s\n", error_message(retval)); + if ((closeval = ext2fs_close(*fs))) + fputs(error_message(closeval), stderr); + *fs = NULL; + return retval; + } + + if ((retval = ext2fs_read_block_bitmap(*fs))) + { + fprintf(stderr, "%s\n", error_message(retval)); + if ((closeval = ext2fs_close(*fs))) + fputs(error_message(closeval), stderr); + *fs = NULL; + return retval; + } + + *root = EXT2_ROOT_INO; + return(0); +} + +long +read_inode(ext2_filsys fs, ext2_ino_t file, struct ext2_inode *inode) +{ + long retval; + + if ((retval = ext2fs_read_inode(fs, file, inode))) + fprintf(stderr, "%s\n", error_message(retval)); + return retval; +} + +long +write_inode(ext2_filsys fs, ext2_ino_t file, struct ext2_inode *inode) +{ + long retval; + + if ((retval = ext2fs_write_inode(fs, file, inode))) + fprintf(stderr, "%s\n", error_message(retval)); + return retval; + +} + +long +rm_file(ext2_filsys fs, ext2_ino_t cwd, char *outfile, ext2_ino_t delfile) +{ + struct ext2_inode inode; + long retval; + + if ((retval = read_inode(fs, delfile, &inode))) + return(retval); + + --inode.i_links_count; + if ((retval = write_inode(fs, delfile, &inode))) + return(retval); + + if ((retval = ext2fs_unlink(fs, cwd, outfile, 0, 0))) + return(retval); + + if (inode.i_links_count == 0) + return(delete_file(fs, delfile)); + + return(0); +} + +long +delete_file(ext2_filsys fs, ext2_ino_t inode) +{ + struct ext2_inode inode_buf; + long retval; + + if ((retval = read_inode(fs, inode, &inode_buf))) + { + fprintf(stderr, "%s\n", error_message(retval)); + return(retval); + } + + inode_buf.i_dtime = time(NULL); + if ((retval = write_inode(fs, inode, &inode_buf))) + { + fprintf(stderr, "%s\n", error_message(retval)); + return(retval); + } + + if ((retval = ext2fs_block_iterate(fs, inode, 0, NULL, + release_blocks_proc, NULL))) + { + fprintf(stderr, "%s\n", error_message(retval)); + return(retval); + } + + ext2fs_inode_alloc_stats(fs, inode, -1); + + return(0); +} + +static int +release_blocks_proc(ext2_filsys fs, blk_t *blocknr, + int blockcnt, void *private) +{ + blk_t block; + + block = *blocknr; + ext2fs_block_alloc_stats(fs, block, -1); + return 0; +} + +void +init_stat_buf(struct stat *buf) +{ + if (buf) + { + memset(buf, 0, sizeof(struct stat)); + buf->st_atime = buf->st_ctime = buf->st_mtime = time(NULL); + buf->st_uid = getuid(); + buf->st_gid = getgid(); + } +} + +int +is_file_regexp(char *ptr) +{ + char c; + + while ((c = *ptr++) != '\0') + { + switch(c) + { + case '*': + case '[': + case ']': + case '?': + return(1); + break; + } + } + return(0); +} + +regex_t * +make_regexp(char *shell) +{ + char *tmpstr; + char *ptr; + static regex_t reg; + int l; + char c; + + if (NULL == (tmpstr = alloca((strlen(shell)) << 1 + 3))) + { + perror("make_regexp"); + return(NULL); + } + + ptr = tmpstr; + *ptr++ = '^'; + + while ((c = *shell++) != '\0') + { + switch(c) + { + case '*': + *ptr++ = '.'; + *ptr++ = c; + break; + case '?': + *ptr++ = '.'; + break; + case '.': + *ptr++ = '\\'; + *ptr++ = '.'; + break; + default: + *ptr++ = c; + } + } + *ptr++ = '$'; + *ptr = '\0'; + + if (regcomp(®, tmpstr, REG_NOSUB)) + { + perror("make_regexp"); + return(NULL); + } + + return(®); +} |