dirblock.c revision 9f8046fc6dfc13eee2f5c363214e60b533872cac
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 do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES| 35 EXT2_FLAG_SWAP_BYTES_READ)) != 0; 36 p = (char *) buf; 37 end = (char *) buf + fs->blocksize; 38 while (p < end-8) { 39 dirent = (struct ext2_dir_entry *) p; 40 if (do_swap) { 41 dirent->inode = ext2fs_swab32(dirent->inode); 42 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 43 dirent->name_len = ext2fs_swab16(dirent->name_len); 44 } 45 rec_len = dirent->rec_len; 46 if ((rec_len < 8) || (rec_len % 4)) { 47 rec_len = 8; 48 retval = EXT2_ET_DIR_CORRUPTED; 49 } 50 dirent2 = (struct ext2_dir_entry_2 *) dirent; 51 if ((dirent2->name_len +8) > dirent2->rec_len) 52 retval = EXT2_ET_DIR_CORRUPTED; 53 p += rec_len; 54 } 55 return retval; 56} 57 58errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block, 59 void *inbuf) 60{ 61 errcode_t retval; 62 char *p, *end, *write_buf; 63 char *buf = 0; 64 struct ext2_dir_entry *dirent; 65 66 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || 67 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) { 68 retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); 69 if (retval) 70 return retval; 71 write_buf = buf; 72 memcpy(buf, inbuf, fs->blocksize); 73 p = buf; 74 end = buf + fs->blocksize; 75 while (p < end) { 76 dirent = (struct ext2_dir_entry *) p; 77 if ((dirent->rec_len < 8) || 78 (dirent->rec_len % 4)) { 79 retval = EXT2_ET_DIR_CORRUPTED; 80 goto errout; 81 } 82 p += dirent->rec_len; 83 dirent->inode = ext2fs_swab32(dirent->inode); 84 dirent->rec_len = ext2fs_swab16(dirent->rec_len); 85 dirent->name_len = ext2fs_swab16(dirent->name_len); 86 } 87 } else 88 write_buf = (char *) inbuf; 89 retval = io_channel_write_blk(fs->io, block, 1, write_buf); 90errout: 91 if (buf) 92 ext2fs_free_mem((void **) &buf); 93 return retval; 94} 95 96 97