blob: f7c42d02b6be082dfc092feacd1a45327efc3e0d [file] [log] [blame]
Theodore Ts'o72ed1262000-11-12 19:32:20 +00001/*
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
Theodore Ts'o3e377db2000-12-09 02:37:33 +000043const char * program_name = "e2image";
Theodore Ts'o72ed1262000-11-12 19:32:20 +000044char * device_name = NULL;
45
46static void usage(void)
47{
48 fprintf(stderr, _("Usage: %s device file\n"), program_name);
49 exit (1);
50}
51
Theodore Ts'o72ed1262000-11-12 19:32:20 +000052static 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;
Theodore Ts'o72ed1262000-11-12 19:32:20 +000082 errcode_t retval;
83 ext2_filsys fs;
Theodore Ts'o72ed1262000-11-12 19:32:20 +000084 int open_flag = 0;
85 int raw_flag = 0;
86 int fd = 0;
Theodore Ts'o72ed1262000-11-12 19:32:20 +000087 struct ext2_image_hdr hdr;
88
89#ifdef ENABLE_NLS
90 setlocale(LC_MESSAGES, "");
91 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
92 textdomain(NLS_CAT_NAME);
93#endif
94 fprintf (stderr, _("e2image %s, %s for EXT2 FS %s, %s\n"),
95 E2FSPROGS_VERSION, E2FSPROGS_DATE,
96 EXT2FS_VERSION, EXT2FS_DATE);
97 if (argc && *argv)
98 program_name = *argv;
99 initialize_ext2_error_table();
100 while ((c = getopt (argc, argv, "r")) != EOF)
101 switch (c) {
102 case 'r':
103 raw_flag++;
104 break;
105 default:
106 usage();
107 }
108 if (optind != argc - 2 )
109 usage();
110 device_name = argv[optind];
111 retval = ext2fs_open (device_name, open_flag, 0, 0,
112 unix_io_manager, &fs);
113 if (retval) {
114 com_err (program_name, retval, _("while trying to open %s"),
115 device_name);
116 printf(_("Couldn't find valid filesystem superblock.\n"));
117 exit(1);
118 }
Theodore Ts'o72ed1262000-11-12 19:32:20 +0000119
120 fd = open(argv[optind+1], O_CREAT|O_TRUNC|O_RDWR, 0600);
121 if (fd < 0) {
122 com_err(program_name, errno, _("while trying to open %s"),
123 argv[optind+1]);
124 exit(1);
125 }
126
127 write_header(fd, NULL);
128 memset(&hdr, 0, sizeof(struct ext2_image_hdr));
129
130 hdr.offset_super = lseek(fd, 0, SEEK_CUR);
131 retval = ext2fs_image_super_write(fs, fd, 0);
132 if (retval) {
133 com_err(program_name, retval, _("while writing superblock"));
134 exit(1);
135 }
136
137 hdr.offset_inode = lseek(fd, 0, SEEK_CUR);
138 retval = ext2fs_image_inode_write(fs, fd, IMAGER_FLAG_SPARSEWRITE);
139 if (retval) {
140 com_err(program_name, retval, _("while writing inode table"));
141 exit(1);
142 }
143
144 hdr.offset_blockmap = lseek(fd, 0, SEEK_CUR);
145 retval = ext2fs_image_bitmap_write(fs, fd, 0);
146 if (retval) {
147 com_err(program_name, retval, _("while writing block bitmap"));
148 exit(1);
149 }
150
151 hdr.offset_inodemap = lseek(fd, 0, SEEK_CUR);
152 retval = ext2fs_image_bitmap_write(fs, fd, IMAGER_FLAG_INODEMAP);
153 if (retval) {
154 com_err(program_name, retval, _("while writing inode bitmap"));
155 exit(1);
156 }
157
158 ext2fs_close (fs);
159 exit (0);
160}