-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.c
154 lines (123 loc) · 3.19 KB
/
util.c
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "util.h"
char *stdin_recv(size_t buffsz)
{
/* i know that sizeof(char) is 1. C sometimes treats chars as inegers.
https://stackoverflow.com/questions/2172943/size-of-character-a-in-c-c */
char *buffer = (char *)malloc(sizeof(char) * buffsz);
size_t i = 0;
register int cr;
do {
if ((cr = getchar()) == '\0' || cr == 0 || cr == EOF) /* if you have a better solution... */
break;
buffer[i] = cr;
} while(++i != buffsz);
if (i != buffsz) {
buffer[i-1] = 0;
return buffer; /* must free after use */
} else {
/* Buffer overflow detected */
return NULL;
}
}
long hextodecimal(char *sbase16)
{
return strtol(sbase16, NULL, 16);
}
/* check filename's length
errors:
0 : no errors returned
-1 : filename length exceded
*/
size_t check_fname_len(const char *fname)
{
if (strnlen(fname, FILENAME_MAX_LENGTH) == FILENAME_MAX_LENGTH)
return -1;
return 0;
}
/* This function returns one of the READALL_.
If the return value is zero == READALL_OK, then:
(*dataptr) points to a dynamically allocated buffer, with
(*sizeptr) chars read from the file.
The buffer is allocated for one extra char, which is NUL,
and automatically appended after the data.
Initial values of (*dataptr) and (*sizeptr) are ignored.
*/
int readall(FILE *in, char **dataptr, size_t *sizeptr)
{
char *data = NULL, *temp;
size_t size = 0;
size_t used = 0;
size_t n;
if (in == NULL || dataptr == NULL || sizeptr == NULL) {
return READALL_INVALID;
}
/* A read error already occurred? */
if (ferror(in)) {
return READALL_ERROR;
}
while (1) {
if (used + READALL_CHUNK + 1 > size) {
size = used + READALL_CHUNK + 1;
/* Overflow check. Some ANSI C compilers
may optimize this away, though. */
if (size <= used) {
free(data);
return READALL_TOOMUCH;
}
temp = realloc(data, size);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
}
n = fread(data + used, 1, READALL_CHUNK, in);
if (n == 0)
break;
used += n;
}
if (ferror(in)) {
free(data);
return READALL_ERROR;
}
temp = realloc(data, used + 1);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
data[used] = '\0';
*dataptr = data;
*sizeptr = used;
return READALL_OK;
}
void handle_readall_errors(int err)
{
switch (err) {
case READALL_INVALID:
fprintf(stderr, "error: invalid parameters\n");
break;
case READALL_ERROR:
fprintf(stderr, "error: cannot read file\n");
break;
case READALL_NOMEM:
fprintf(stderr, "error: out of memory\n");
break;
case READALL_TOOMUCH:
fprintf(stderr, "error: overflow check\n");
break;
}
}
int prepare_read(char **buff, size_t sz, char *filename)
{
FILE *f = fopen(filename, "rb");
int read = readall(f, buff, &sz);
if (read != 0)
return read;
fclose(f);
return read;
}