dirblock.c revision 5df55d7f847e29d23227592a0bb23daad1a61500
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_block(ext2_filsys fs, blk_t block, 23 void *buf) 24{ 25 errcode_t retval; 26 char *p, *end; 27 struct ext2_dir_entry *dirent; 28 struct ext2_dir_entry_2 *dirent2; 29 unsigned int rec_len, do_swap; 30 31 retval = io_channel_read_blk(fs->io, block, 1, buf); 32 if (retval) 33 return retval; 34#ifdef EXT2FS_ENABLE_SWAPFS 35 do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES| 36 EXT2_FLAG_SWAP_BYTES_READ)) != 0; 37#endif 38 p = (char *) buf; 39 end = (char *) buf + fs->blocksize; 40 while (p < end-8) { 41 dirent = (struct ext2_dir_entry *) p; 42#ifdef EXT2FS_ENABLE_SWAPFS 43 if (do_swap) { 44 dirent->inode = ext2fs_swab32(dirent->inode); 45 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 46 dirent->name_len = ext2fs_swab16(dirent->name_len); 47 } 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 dirent2 = (struct ext2_dir_entry_2 *) dirent; 55 if ((dirent2->name_len +8) > dirent2->rec_len) 56 retval = EXT2_ET_DIR_CORRUPTED; 57 p += rec_len; 58 } 59 return retval; 60} 61 62errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block, 63 void *inbuf) 64{ 65 errcode_t retval; 66 char *p, *end, *write_buf; 67 char *buf = 0; 68 struct ext2_dir_entry *dirent; 69 70#ifdef EXT2FS_ENABLE_SWAPFS 71 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 72 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) { 73 retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); 74 if (retval) 75 return retval; 76 write_buf = buf; 77 memcpy(buf, inbuf, fs->blocksize); 78 p = buf; 79 end = buf + fs->blocksize; 80 while (p < end) { 81 dirent = (struct ext2_dir_entry *) p; 82 if ((dirent->rec_len < 8) || 83 (dirent->rec_len % 4)) { 84 retval = EXT2_ET_DIR_CORRUPTED; 85 goto errout; 86 } 87 p += dirent->rec_len; 88 dirent->inode = ext2fs_swab32(dirent->inode); 89 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 90 dirent->name_len = ext2fs_swab16(dirent->name_len); 91 } 92 } else 93#endif 94 write_buf = (char *) inbuf; 95 retval = io_channel_write_blk(fs->io, block, 1, write_buf); 96errout: 97 if (buf) 98 ext2fs_free_mem((void **) &buf); 99 return retval; 100} 101 102 103