(write_string): Treat short item count as an error.
[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 #include "io.h"
34
35 #define RANDOM_DEVICE "/dev/urandom"
36 #define BUFSIZE 1000
37
38 int quiet_flag = 0;
39
40 void
41 werror(const char *format, ...)
42 {
43   if (!quiet_flag)
44     {
45       va_list args;
46       va_start(args, format);
47       vfprintf(stderr, format, args);
48       va_end(args);
49     }
50 }
51
52 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
53
54 unsigned
55 read_file(const char *name, unsigned max_size, char **contents)
56 {
57   unsigned size;
58   unsigned done;
59   char *buffer;
60   FILE *f;
61     
62   f = fopen(name, "rb");
63   if (!f)
64     return 0;
65
66   buffer = NULL;
67
68   if (max_size && max_size < 100)
69     size = max_size;
70   else
71     size = 100;
72   
73   for (size = 100, done = 0;
74        (!max_size || done < max_size) && !feof(f);
75        size *= 2)
76     {
77       char *p;
78
79       if (max_size && size > max_size)
80         size = max_size;
81
82       /* Space for terminating NUL */
83       p = realloc(buffer, size + 1);
84
85       if (!p)
86         {
87         fail:
88           fclose(f);
89           free(buffer);
90           *contents = NULL;
91           return 0;
92         }
93
94       buffer = p;
95       done += fread(buffer + done, 1, size - done, f);
96
97       if (ferror(f))
98         goto fail;
99     }
100   
101   fclose(f);
102
103   /* NUL-terminate the data. */
104   buffer[done] = '\0';
105   *contents = buffer;
106   
107   return done;
108 }
109
110 int
111 write_file(const char *name, unsigned size, const char *buffer)
112 {
113   FILE *f = fopen(name, "wb");
114   unsigned res;
115   
116   if (!f)
117     return 0;
118
119   res = fwrite(buffer, 1, size, f);
120   
121   if (res < size)
122     res = 0;
123
124   return fclose(f) == 0 && res > 0;
125 }
126
127 int
128 write_string(FILE *f, unsigned size, const char *buffer)
129 {
130   size_t res = fwrite(buffer, 1, size, f);
131
132   return res == size;
133 }
134
135 int
136 simple_random(struct yarrow256_ctx *ctx, const char *name)
137 {
138   unsigned length;
139   char *buffer;
140
141   if (name)
142     length = read_file(name, 0, &buffer);
143   else
144     length = read_file(RANDOM_DEVICE, 20, &buffer);
145   
146   if (!length)
147     return 0;
148
149   yarrow256_seed(ctx, length, buffer);
150
151   return 1;
152 }
153
154 int
155 hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
156 {
157   for (;;)
158     {
159       char buffer[BUFSIZE];
160       size_t res = fread(buffer, 1, sizeof(buffer), f);
161       if (ferror(f))
162         return 0;
163       
164       hash->update(ctx, res, buffer);
165       if (feof(f))
166         return 1;
167     }
168 }
169
170 #if WITH_PUBLIC_KEY
171 int
172 read_rsa_key(const char *name,
173              struct rsa_public_key *pub,
174              struct rsa_private_key *priv)
175 {
176   unsigned length;
177   char *buffer;
178   int res;
179   
180   length = read_file(name, 0, &buffer);
181   if (!length)
182     return 0;
183
184   res = rsa_keypair_from_sexp(pub, priv, 0, length, buffer);
185   free(buffer);
186
187   return res;
188 }
189 #endif /* WITH_PUBLIC_KEY */