]> git.ipfire.org Git - thirdparty/util-linux.git/blob - historic/makehole.c
Imported from util-linux-2.5 tarball.
[thirdparty/util-linux.git] / historic / makehole.c
1 /* makehole.c - original by HJ Lu */
2
3 /* Patched by faith@cs.unc.edu, Wed Oct 6 18:01:39 1993 based on
4 information from Michael Bischoff <mbi@mo.math.nat.tu-bs.de> (Fri, 18
5 Jun 93 10:10:19 +0200). */
6
7 #include <unistd.h>
8 #include <fcntl.h>
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <errno.h>
12 #include <a.out.h>
13
14 #define BUFSIZE 1024
15 #undef DEBUG
16
17 void usage(char *name, char *message)
18 {
19 if (message)
20 fprintf(stderr, "%s: %s\n", name, message);
21
22 if (errno)
23 perror(name);
24
25 fprintf(stderr, "Usage:%s Imagefile\n", name);
26 exit(1);
27 }
28
29 int ishole(char *buf, int size)
30 {
31 int i;
32
33 for (i = 0; i < size; i++)
34 if (buf[i])
35 return 0;
36
37 return 1;
38 }
39
40 void main(int argc, char *argv[])
41 {
42 char buf[BUFSIZE];
43 char tmp_file[64];
44 int fdin, fdout;
45 int ret;
46 int abs_offset;
47 int hole;
48 struct exec *header = (struct exec *) buf;
49
50 #ifndef DEBUG
51 if (geteuid()) {
52 fprintf(stderr, "%s: must be root to run!\n", *argv);
53 exit(1);
54 }
55 #endif
56
57 switch (argc) {
58 case 2:
59 break;
60 default:
61 usage(*argv, NULL);
62 }
63
64 errno = 0;
65
66 sprintf( tmp_file, "hole%d", getpid() );
67 if (tmp_file == NULL) {
68 usage(*argv, "Unable to get a temporary image filename!");
69 }
70 #ifdef DEBUG
71 else {
72 fprintf(stderr, "Temparory image file: %s\n", tmp_file);
73 }
74 #endif
75
76 errno = 0;
77 fdin = open(argv[1], O_RDONLY);
78 if (fdin == -1) {
79 usage(*argv, "unable to open file.");
80 }
81 fprintf(stderr, "Making holes in %s...\n", argv[1]);
82
83 errno = 0;
84
85 if ((ret = read(fdin, header, BUFSIZE)) != BUFSIZE
86 || N_MAGIC(*header) != ZMAGIC) {
87 usage(*argv, "file must be pure executable.");
88 }
89
90 fdout = creat(tmp_file, 0555);
91 if (fdout == -1) {
92 perror("Unable to create the temparory image file!");
93 exit(1);
94 }
95 if (write(fdout, header, ret) != ret) {
96 perror("Fail to write header to the temparory image file!");
97 unlink(tmp_file);
98 exit(1);
99 }
100 abs_offset = ret;
101 hole = 0;
102 while ((ret = read(fdin, buf, BUFSIZE)) > 0) {
103 abs_offset += ret;
104 if (ishole(buf, ret)) {
105 #ifdef DEBUG
106 fprintf(stderr, "There is a %d byte hole from 0x%x to 0x%x.\n", ret, abs_offset - ret, abs_offset);
107 #endif
108 hole += ret;
109 if (lseek(fdout, abs_offset, SEEK_SET) != abs_offset) {
110 perror("Fail to make a hole in the temparory image file!");
111 unlink(tmp_file);
112 exit(1);
113 }
114 } else {
115 #ifdef DEBUG
116 fprintf(stderr, "Writing %d bytes from 0x%x to 0x%x.\n", ret, abs_offset - ret, abs_offset);
117 #endif
118 if (write(fdout, buf, ret) != ret) {
119 perror("Fail to write the temparory image file!");
120 unlink(tmp_file);
121 exit(1);
122 }
123 }
124 }
125
126 if (ftruncate(fdout, abs_offset)) {
127 perror("Fail to truncate the temparory image file!");
128 unlink(tmp_file);
129 exit(1);
130 }
131 close(fdout);
132 close(fdin);
133
134 if (rename(tmp_file, argv[1])) {
135 perror("Fail to rename the temparory image file to the old image file!");
136 unlink(tmp_file);
137 exit(1);
138 }
139 fprintf(stderr, "There are %d byte holes out of %d bytes in `%s'.\n", hole, abs_offset, argv[1]);
140 }