(read_file): Bug fix, in dependence on initial size on max_size.
[gd/nettle] / examples / io.c
1 /* io.c
2  *
3  * Miscellaneous functions used by the example programs.
4  */
5
6 /* nettle, low-level cryptographics library
7  *
8  * Copyright (C) 2002 Niels Möller
9  *  
10  * The nettle library is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as published by
12  * the Free Software Foundation; either version 2.1 of the License, or (at your
13  * option) any later version.
14  * 
15  * The nettle library is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18  * License for more details.
19  * 
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with the nettle library; see the file COPYING.LIB.  If not, write to
22  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23  * MA 02111-1307, USA.
24  */
25
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <stdarg.h>
31 #include <stdlib.h>
32
33 /* For errno and strerror */
34 #include <errno.h>
35 #include <string.h>
36
37 #include "io.h"
38
39 #define RANDOM_DEVICE "/dev/urandom"
40 #define BUFSIZE 1000
41
42 int quiet_flag = 0;
43
44 void *
45 xalloc(size_t size)
46 {
47   void *p = malloc(size);
48   if (!p)
49     {
50       fprintf(stderr, "Virtual memory exhausted.\n");
51       abort();
52     }
53
54   return p;
55 }
56
57 void
58 werror(const char *format, ...)
59 {
60   if (!quiet_flag)
61     {
62       va_list args;
63       va_start(args, format);
64       vfprintf(stderr, format, args);
65       va_end(args);
66     }
67 }
68
69 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
70
71 unsigned
72 read_file(const char *name, unsigned max_size, char **contents)
73 {
74   unsigned size;
75   unsigned done;
76   char *buffer;
77   FILE *f;
78     
79   f = fopen(name, "rb");
80   if (!f)
81     {
82       werror("Opening `%s' failed: %s\n", name, strerror(errno));
83       return 0;
84     }
85   buffer = NULL;
86
87   if (max_size && max_size < 100)
88     size = max_size;
89   else
90     size = 100;
91
92   /* FIXME: The use of feof and ferror in this loop is a bit confused
93      (but I think it is still correct). We should check the return
94      value of fread, and call feof and/or ferror when we get a short
95      item count. */     
96
97   for (done = 0;
98        (!max_size || done < max_size) && !feof(f);
99        size *= 2)
100     {
101       char *p;
102
103       if (max_size && size > max_size)
104         size = max_size;
105
106       /* Space for terminating NUL */
107       p = realloc(buffer, size + 1);
108
109       if (!p)
110         {
111         fail:
112           fclose(f);
113           free(buffer);
114           *contents = NULL;
115           return 0;
116         }
117
118       buffer = p;
119       done += fread(buffer + done, 1, size - done, f);
120
121       if (ferror(f))
122         goto fail;
123     }
124   
125   fclose(f);
126
127   /* NUL-terminate the data. */
128   buffer[done] = '\0';
129   *contents = buffer;
130   
131   return done;
132 }
133
134 int
135 write_file(const char *name, unsigned size, const char *buffer)
136 {
137   FILE *f = fopen(name, "wb");
138   unsigned res;
139   
140   if (!f)
141     return 0;
142
143   res = fwrite(buffer, 1, size, f);
144   
145   if (res < size)
146     res = 0;
147
148   return fclose(f) == 0 && res > 0;
149 }
150
151 int
152 write_string(FILE *f, unsigned size, const char *buffer)
153 {
154   size_t res = fwrite(buffer, 1, size, f);
155
156   return res == size;
157 }
158
159 int
160 simple_random(struct yarrow256_ctx *ctx, const char *name)
161 {
162   unsigned length;
163   char *buffer;
164
165   if (name)
166     length = read_file(name, 0, &buffer);
167   else
168     length = read_file(RANDOM_DEVICE, 20, &buffer);
169   
170   if (!length)
171     return 0;
172
173   yarrow256_seed(ctx, length, buffer);
174
175   free(buffer);
176
177   return 1;
178 }
179
180 int
181 hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
182 {
183   for (;;)
184     {
185       char buffer[BUFSIZE];
186       size_t res = fread(buffer, 1, sizeof(buffer), f);
187       if (ferror(f))
188         return 0;
189       
190       hash->update(ctx, res, buffer);
191       if (feof(f))
192         return 1;
193     }
194 }