1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
typedef void (*toes_func)(void);
void even_toes(void) {
printf("with even-toed hoofs");
}
void odd_toes(void) {
printf("with odd-toed hoofs");
}
/* Assume this function has the address 0x4012ce */
void shellcode(void) {
printf("Uh-oh, this looks like some sort of attack\n");
exit(42);
}
struct herbivore {
struct herbivore *next;
toes_func func;
};
struct herbivore *herbivore_list = 0;
struct carnivore {
struct carnivore *next;
long num_teeth;
};
struct carnivore *carnivore_list = 0;
#define NUM_ANIMALS 256
/* Initialized to all null pointers */
void *animals_by_num[NUM_ANIMALS];
void new_herbivore(long x) {
int loc = x & (NUM_ANIMALS - 1);
struct herbivore *hp = malloc(sizeof(struct herbivore));
printf("Allocating herbivore at %p\n", hp);
if (!hp)
exit(1);
if (x & 1)
hp->func = odd_toes;
else
hp->func = even_toes;
hp->next = herbivore_list;
herbivore_list = hp;
animals_by_num[loc] = hp;
}
void new_carnivore(long x) {
int loc = x & (NUM_ANIMALS - 1);
struct carnivore *cp = malloc(sizeof(struct carnivore));
printf("Allocating carnivore at %p\n", cp);
if (!cp)
exit(1);
cp->num_teeth = x;
cp->next = carnivore_list;
carnivore_list = cp;
animals_by_num[loc] = cp;
}
void release_animal(long x) {
int loc = x & (NUM_ANIMALS - 1);
if (!animals_by_num[loc]) {
fprintf(stderr, "Attempt to release non-existant animal\n");
exit(1);
}
free(animals_by_num[loc]);
animals_by_num[loc] = 0;
}
void list_animals(void) {
struct herbivore *hp;
struct carnivore *cp;
for (hp = herbivore_list; hp; hp = hp->next) {
printf("A herbivore ");
(hp->func)();
printf("\n");
}
for (cp = carnivore_list; cp; cp = cp->next) {
printf("A carnivore with %ld teeth\n", cp->num_teeth);
}
}
void syntax_error(void) {
fprintf(stderr, "Unrecognized syntax\n");
exit(1);
}
int main(int argc, char **argv) {
for (;;) {
int c = getchar();
long x;
while (isspace(c))
c = getchar();
if (c == EOF)
return 0;
switch (c) {
case 'h':
if (scanf(" %li", &x) != 1)
syntax_error();
new_herbivore(x);
break;
case 'c':
if (scanf(" %li", &x) != 1)
syntax_error();
new_carnivore(x);
break;
case 'r':
if (scanf(" %li", &x) != 1)
syntax_error();
release_animal(x);
break;
case 'l':
list_animals();
break;
case 'q':
return 0;
break;
default:
fprintf(stderr, "Unrecognized command %c\n", c);
exit(1);
}
}
}
|