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