e2image.c revision c5423c5b3ea549d96d1b3315a96b5b58beca75cd
1/* 2 * e2image.c --- Program which writes an image file backing up 3 * critical metadata for the filesystem. 4 * 5 * Copyright 2000 by Theodore Ts'o. 6 * 7 * %Begin-Header% 8 * This file may be redistributed under the terms of the GNU Public 9 * License. 10 * %End-Header% 11 */ 12 13#include <fcntl.h> 14#include <grp.h> 15#ifdef HAVE_GETOPT_H 16#include <getopt.h> 17#else 18extern char *optarg; 19extern int optind; 20#endif 21#include <pwd.h> 22#include <stdio.h> 23#include <stdlib.h> 24#include <string.h> 25#include <time.h> 26#include <unistd.h> 27#include <fcntl.h> 28#include <errno.h> 29#include <sys/stat.h> 30#include <sys/types.h> 31 32#include <linux/ext2_fs.h> 33 34#include "ext2fs/ext2fs.h" 35#include "et/com_err.h" 36#include "uuid/uuid.h" 37#include "e2p/e2p.h" 38#include "ext2fs/e2image.h" 39 40#include "../version.h" 41#include "nls-enable.h" 42 43const char * program_name = "e2image"; 44char * device_name = NULL; 45 46static void usage(void) 47{ 48 fprintf(stderr, _("Usage: %s device file\n"), program_name); 49 exit (1); 50} 51 52static void write_header(int fd, struct ext2_image_hdr *hdr) 53{ 54 char header_buf[4096]; 55 int actual; 56 57 if (lseek(fd, 0, SEEK_SET) < 0) { 58 perror("lseek while writing header"); 59 exit(1); 60 } 61 memset(header_buf, 0, sizeof(header_buf)); 62 63 if (hdr) 64 memcpy(header_buf, hdr, sizeof(struct ext2_image_hdr)); 65 66 actual = write(fd, header_buf, sizeof(header_buf)); 67 if (actual < 0) { 68 perror("write header"); 69 exit(1); 70 } 71 if (actual != sizeof(header_buf)) { 72 fprintf(stderr, _("short write (only %d bytes) for" 73 "writing image header"), actual); 74 exit(1); 75 } 76} 77 78 79int main (int argc, char ** argv) 80{ 81 int c; 82 errcode_t retval; 83 ext2_filsys fs; 84 int open_flag = 0; 85 int raw_flag = 0; 86 int fd = 0; 87 struct ext2_image_hdr hdr; 88 struct stat st; 89 90#ifdef ENABLE_NLS 91 setlocale(LC_MESSAGES, ""); 92 bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 93 textdomain(NLS_CAT_NAME); 94#endif 95 fprintf (stderr, _("e2image %s, %s for EXT2 FS %s, %s\n"), 96 E2FSPROGS_VERSION, E2FSPROGS_DATE, 97 EXT2FS_VERSION, EXT2FS_DATE); 98 if (argc && *argv) 99 program_name = *argv; 100 initialize_ext2_error_table(); 101 while ((c = getopt (argc, argv, "r")) != EOF) 102 switch (c) { 103 case 'r': 104 raw_flag++; 105 break; 106 default: 107 usage(); 108 } 109 if (optind != argc - 2 ) 110 usage(); 111 device_name = argv[optind]; 112 retval = ext2fs_open (device_name, open_flag, 0, 0, 113 unix_io_manager, &fs); 114 if (retval) { 115 com_err (program_name, retval, _("while trying to open %s"), 116 device_name); 117 printf(_("Couldn't find valid filesystem superblock.\n")); 118 exit(1); 119 } 120 121 fd = open(argv[optind+1], O_CREAT|O_RDWR, 0600); 122 if (fd < 0) { 123 com_err(program_name, errno, _("while trying to open %s"), 124 argv[optind+1]); 125 exit(1); 126 } 127 128 write_header(fd, NULL); 129 memset(&hdr, 0, sizeof(struct ext2_image_hdr)); 130 131 hdr.offset_super = lseek(fd, 0, SEEK_CUR); 132 retval = ext2fs_image_super_write(fs, fd, 0); 133 if (retval) { 134 com_err(program_name, retval, _("while writing superblock")); 135 exit(1); 136 } 137 138 hdr.offset_inode = lseek(fd, 0, SEEK_CUR); 139 retval = ext2fs_image_inode_write(fs, fd, IMAGER_FLAG_SPARSEWRITE); 140 if (retval) { 141 com_err(program_name, retval, _("while writing inode table")); 142 exit(1); 143 } 144 145 hdr.offset_blockmap = lseek(fd, 0, SEEK_CUR); 146 retval = ext2fs_image_bitmap_write(fs, fd, 0); 147 if (retval) { 148 com_err(program_name, retval, _("while writing block bitmap")); 149 exit(1); 150 } 151 152 hdr.offset_inodemap = lseek(fd, 0, SEEK_CUR); 153 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP); 154 if (retval) { 155 com_err(program_name, retval, _("while writing inode bitmap")); 156 exit(1); 157 } 158 159 hdr.magic_number = EXT2_ET_MAGIC_E2IMAGE; 160 strcpy(hdr.magic_descriptor, "Ext2 Image 1.0"); 161 gethostname(hdr.fs_hostname, sizeof(hdr.fs_hostname)); 162 163 if (stat(device_name, &st) == 0) 164 hdr.fs_device = st.st_rdev; 165 166 if (fstat(fd, &st) == 0) { 167 hdr.image_device = st.st_dev; 168 hdr.image_inode = st.st_ino; 169 } 170 memcpy(hdr.fs_uuid, fs->super->s_uuid, sizeof(hdr.fs_uuid)); 171 172 hdr.image_time = time(0); 173 write_header(fd, &hdr); 174 175 ext2fs_close (fs); 176 exit (0); 177} 178 179 180