]> pd.if.org Git - zpackage/blob - elf/elftype.c
remove debugging printf
[zpackage] / elf / elftype.c
1 #define _POSIX_C_SOURCE 200112L
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <fcntl.h>
5 #include <unistd.h>
6 #include <limits.h>
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <elf.h>
11
12 #define RELOCATABLE 0x1
13 #define EXECUTABLE  0x2
14 #define DYNAMIC     0x4
15 #define CORE        0x8
16 #define SYMLINKS    0x10
17
18 int readline(FILE *f, char *fn);
19 int checkfile(char *fn, unsigned int want, int perr, int quiet);
20
21 int errors = 0;
22 int zeroterm = 0;
23
24 int main(int ac, char **av) {
25         int option;
26         unsigned int want = 0;
27         int quiet = 0;
28         int printtype = 0;
29         int printname = 0;
30         int verbose = 0;
31         int perr = 0;
32         FILE *list = 0;
33         char fn[PATH_MAX];
34         
35         while ((option = getopt(ac, av, "vtnredclaqp0f:")) != -1) {
36                 switch (option) {
37                         case 'r': want |= RELOCATABLE; break;
38                         case 'e': want |= EXECUTABLE; break;
39                         case 'd': want |= DYNAMIC; break;
40                         case 'c': want |= CORE; break;
41                         case 'l': want |= SYMLINKS; break;
42                         case 'a': want = (RELOCATABLE|EXECUTABLE|DYNAMIC|CORE); break;
43                         case 'q': quiet++; break;
44                         case 't': printtype++; break;
45                         case 'n': printname++; break;
46                         case 'v': verbose++; break;
47                         case 'p': perr++; break;
48                         case '0': zeroterm = 1; break;
49                         case 'f':
50                                   if (optarg[0] == '-' && optarg[1] == 0) {
51                                           fprintf(stderr, "opening stdin\n");
52                                           list = stdin;
53                                   } else {
54                                           list = fopen(optarg, "r");
55                                   }
56                                   break;
57                         default:
58                                   exit(1);
59                                   break;
60                 }
61         }
62
63         if (!want) want = (RELOCATABLE|EXECUTABLE|DYNAMIC|CORE);
64
65         if (list) {
66                 quiet = 2;
67                 perr = 0;
68                 while (readline(list, fn)) {
69                         if (checkfile(fn, want,perr,quiet)) {
70                                 printf("%s\n", fn);
71                         }
72                 }
73         } else {
74                 int type;
75                 char *fn;
76
77                 fn = av[optind];
78                 if (verbose) fprintf(stderr, "checking %s\n", av[optind]);
79                 type = checkfile(fn,want,perr,quiet);
80
81                 if (printtype) {
82                         switch (type) {
83                                 case RELOCATABLE:
84                                         printf("relocatable"); break;
85                                 case EXECUTABLE:
86                                         printf("executable"); break;
87                                 case DYNAMIC:
88                                         printf("dynamic"); break;
89                                 case CORE:
90                                         printf("core"); break;
91                                 default:
92                                         printf("notelf"); break;
93                         }
94                 }
95
96                 if (printname) {
97                         printf("%s%s", printtype ? " " : "", fn);
98                 }
99                 if (printtype || printname) printf("\n");
100
101                 return type & want ? 0 : 1;
102         }
103         return errors ? 1 : 0;
104 }
105
106 int readline(FILE *f, char *fn) {
107         int ch;
108         int i = 0;
109
110         do {
111                 ch = fgetc(f);
112                 switch (ch) {
113                         case EOF: break;
114                         case 0:
115                                   if (i == 0) continue;
116                                   break;
117                         case '\n':
118                                   if (!zeroterm) {
119                                           if (i == 0) continue;
120                                           break;
121                                   }
122                         default:
123                                   fn[i++] = ch;
124                                   continue;
125                 }
126                 if (i >= PATH_MAX) {
127                         /* TODO print an error */
128                         return 0;
129                 }
130                 fn[i] = 0;
131                 return i;
132         } while (ch != EOF);
133         return 0;
134 }
135
136 int checkfile(char *fn, unsigned int want, int perr, int quiet) {
137         Elf64_Ehdr hdr;
138         int fd, bytes;
139         int endian = 0;
140         struct stat st;
141
142         if (want & SYMLINKS) {
143                 lstat(fn, &st);
144         } else {
145                 stat(fn, &st);
146         }
147         if (!S_ISREG(st.st_mode)) {
148                 return 0;
149         }
150         
151         fd = open(fn, O_RDONLY);
152         if (fd == -1) {
153                 perror("elfcheck");
154                 errors++;
155                 return 0;
156         }
157         bytes = read(fd, &hdr, sizeof hdr);
158         close(fd);
159         if (bytes < sizeof hdr) {
160                 if (perr) fprintf(stderr, "could not read full elf header (wanted %zu got %d bytes)\n", sizeof hdr, bytes);
161                 return 0;
162         }
163         if (hdr.e_ident[EI_MAG0] != ELFMAG0
164                         || hdr.e_ident[EI_MAG1] != ELFMAG1
165                         || hdr.e_ident[EI_MAG2] != ELFMAG2
166                         || hdr.e_ident[EI_MAG3] != ELFMAG3
167            ) {
168                 if (perr) fprintf(stderr, "elf header magic wrong\n");
169                 return 0;
170         }
171         switch (hdr.e_ident[EI_CLASS]) {
172                 case ELFCLASS64:
173                 case ELFCLASS32:
174                 case ELFCLASSNONE:
175                         break;
176                 default:
177                         if (perr) fprintf(stderr, "elf header unknown class\n");
178                         return 0;
179         }
180
181         endian = hdr.e_ident[EI_DATA];
182         switch (endian) {
183                 case ELFDATA2LSB: break;
184                 case ELFDATA2MSB: break;
185                                   /* TODO swap endian if needed */
186                 default:
187                         if (perr) fprintf(stderr, "elf header unknown endian\n");
188                         return 0;
189         }
190
191         switch (hdr.e_type) {
192                 case ET_REL: return RELOCATABLE;
193                 case ET_EXEC: return EXECUTABLE;
194                 case ET_DYN: return DYNAMIC;
195                 case ET_CORE: return CORE;
196                 case ET_NONE:
197                 default:
198                         if (perr) fprintf(stderr, "unknown %s\n", fn);
199                         return 0;
200         }
201
202         return 0;
203 }