dirblock.c revision 126a291c768b523bc228b276d3bea82675a86d09
1/* 2 * dirblock.c --- directory block routines. 3 * 4 * Copyright (C) 1995, 1996 Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Public 8 * License. 9 * %End-Header% 10 */ 11 12#include <stdio.h> 13#if HAVE_UNISTD_H 14#include <unistd.h> 15#endif 16#include <string.h> 17#include <time.h> 18 19#include "ext2_fs.h" 20#include "ext2fs.h" 21 22errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block, 23 void *buf, int flags EXT2FS_ATTR((unused))) 24{ 25 errcode_t retval; 26 char *p, *end; 27 struct ext2_dir_entry *dirent; 28 unsigned int name_len, rec_len; 29 30 31 retval = io_channel_read_blk(fs->io, block, 1, buf); 32 if (retval) 33 return retval; 34 35 p = (char *) buf; 36 end = (char *) buf + fs->blocksize; 37 while (p < end-8) { 38 dirent = (struct ext2_dir_entry *) p; 39#ifdef WORDS_BIGENDIAN 40 dirent->inode = ext2fs_swab32(dirent->inode); 41 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 42 dirent->name_len = ext2fs_swab16(dirent->name_len); 43#endif 44 name_len = dirent->name_len; 45#ifdef WORDS_BIGENDIAN 46 if (flags & EXT2_DIRBLOCK_V2_STRUCT) 47 dirent->name_len = ext2fs_swab16(dirent->name_len); 48#endif 49 rec_len = dirent->rec_len; 50 if ((rec_len < 8) || (rec_len % 4)) { 51 rec_len = 8; 52 retval = EXT2_ET_DIR_CORRUPTED; 53 } 54 if (((name_len & 0xFF) + 8) > dirent->rec_len) 55 retval = EXT2_ET_DIR_CORRUPTED; 56 p += rec_len; 57 } 58 return retval; 59} 60 61errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block, 62 void *buf) 63{ 64 return ext2fs_read_dir_block2(fs, block, buf, 0); 65} 66 67 68errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block, 69 void *inbuf, int flags EXT2FS_ATTR((unused))) 70{ 71#ifdef WORDS_BIGENDIAN 72 errcode_t retval; 73 char *p, *end; 74 char *buf = 0; 75 struct ext2_dir_entry *dirent; 76 77 retval = ext2fs_get_mem(fs->blocksize, &buf); 78 if (retval) 79 return retval; 80 memcpy(buf, inbuf, fs->blocksize); 81 p = buf; 82 end = buf + fs->blocksize; 83 while (p < end) { 84 dirent = (struct ext2_dir_entry *) p; 85 if ((dirent->rec_len < 8) || 86 (dirent->rec_len % 4)) { 87 ext2fs_free_mem(&buf); 88 return (EXT2_ET_DIR_CORRUPTED); 89 } 90 p += dirent->rec_len; 91 dirent->inode = ext2fs_swab32(dirent->inode); 92 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 93 dirent->name_len = ext2fs_swab16(dirent->name_len); 94 95 if (flags & EXT2_DIRBLOCK_V2_STRUCT) 96 dirent->name_len = ext2fs_swab16(dirent->name_len); 97 } 98 retval = io_channel_write_blk(fs->io, block, 1, buf); 99 ext2fs_free_mem(&buf); 100 return retval; 101#else 102 return io_channel_write_blk(fs->io, block, 1, (char *) inbuf); 103#endif 104} 105 106 107errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block, 108 void *inbuf) 109{ 110 return ext2fs_write_dir_block2(fs, block, inbuf, 0); 111} 112 113