io.c 3.63 KB
Newer Older
1
/* io.c
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

   Miscellaneous functions used by the example programs.

   Copyright (C) 2002, 2012 Niels Möller

   This file is part of GNU Nettle.

   GNU Nettle is free software: you can redistribute it and/or
   modify it under the terms of either:

     * the GNU Lesser General Public License as published by the Free
       Software Foundation; either version 3 of the License, or (at your
       option) any later version.

   or

     * the GNU General Public License as published by the Free
       Software Foundation; either version 2 of the License, or (at your
       option) any later version.

   or both in parallel, as here.

   GNU Nettle is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received copies of the GNU General Public License and
   the GNU Lesser General Public License along with this program.  If
   not, see http://www.gnu.org/licenses/.
*/
33
34
35

#if HAVE_CONFIG_H
# include "config.h"
36
#endif
37
38
39
40

#include <stdarg.h>
#include <stdlib.h>

41
42
43
44
/* For errno and strerror */
#include <errno.h>
#include <string.h>

45
46
#include "io.h"

47
48
49
50
51
#define RANDOM_DEVICE "/dev/urandom"
#define BUFSIZE 1000

int quiet_flag = 0;

Niels Möller's avatar
Niels Möller committed
52
53
54
55
56
57
58
59
60
61
62
63
64
void *
xalloc(size_t size)
{
  void *p = malloc(size);
  if (!p)
    {
      fprintf(stderr, "Virtual memory exhausted.\n");
      abort();
    }

  return p;
}

65
66
67
68
69
70
71
72
73
74
75
76
void
werror(const char *format, ...)
{
  if (!quiet_flag)
    {
      va_list args;
      va_start(args, format);
      vfprintf(stderr, format, args);
      va_end(args);
    }
}

77
78
size_t
read_file(const char *name, size_t max_size, uint8_t **contents)
79
{
80
81
  size_t size, done;
  uint8_t *buffer;
82
83
84
85
  FILE *f;
    
  f = fopen(name, "rb");
  if (!f)
86
    {
87
      werror("Opening `%s' failed: %s\n", name, strerror(errno));
88
89
      return 0;
    }
90

Niels Möller's avatar
Niels Möller committed
91
  size = 100;
92

Niels Möller's avatar
Niels Möller committed
93
  for (buffer = NULL, done = 0;; size *= 2)
94
    {
95
      uint8_t *p;
96

97
      if (max_size && size > max_size)
98
99
100
	size = max_size;

      /* Space for terminating NUL */
101
      p = realloc(buffer, size + 1);
102
103
104
105
106

      if (!p)
	{
	fail:
	  fclose(f);
107
108
	  free(buffer);
	  *contents = NULL;
109
110
111
	  return 0;
	}

112
      buffer = p;
113
114
      done += fread(buffer + done, 1, size - done, f);

Niels Möller's avatar
Niels Möller committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
      if (done < size)
	{
	  /* Short count means EOF or read error */
	  if (ferror(f))
	    {
	      fprintf (stderr, "Reading `%s' failed: %s\n",
		       name, strerror(errno));

	      goto fail;
	    }
	  if (done == 0)
	    /* Treat empty file as error */
	    goto fail;

	  break;
	}

      if (size == max_size)
	break;
134
135
136
137
138
    }
  
  fclose(f);

  /* NUL-terminate the data. */
139
140
141
  buffer[done] = '\0';
  *contents = buffer;
  
142
143
144
145
  return done;
}

int
146
write_data(FILE *f, size_t size, const void *buffer)
147
{
148
  size_t res = fwrite(buffer, 1, size, f);
149

150
  return res == size;
Niels Möller's avatar
Niels Möller committed
151
152
153
}

int
154
write_file(const char *name, size_t size, const void *buffer)
Niels Möller's avatar
Niels Möller committed
155
{
156
157
158
159
160
  FILE *f = fopen(name, "wb");
  int res;
  
  if (!f)
    return 0;
161

162
  res = write_data(f, size, buffer);
163
  return fclose(f) == 0 && res;
164
165
166
167
168
169
}

int
simple_random(struct yarrow256_ctx *ctx, const char *name)
{
  unsigned length;
170
  uint8_t *buffer;
171
172
173
174
175
176
177
178
179
180
181

  if (name)
    length = read_file(name, 0, &buffer);
  else
    length = read_file(RANDOM_DEVICE, 20, &buffer);
  
  if (!length)
    return 0;

  yarrow256_seed(ctx, length, buffer);

182
183
  free(buffer);

184
185
186
187
188
189
190
191
  return 1;
}

int
hash_file(const struct nettle_hash *hash, void *ctx, FILE *f)
{
  for (;;)
    {
192
      uint8_t buffer[BUFSIZE];
193
194
195
196
197
198
199
200
201
      size_t res = fread(buffer, 1, sizeof(buffer), f);
      if (ferror(f))
	return 0;
      
      hash->update(ctx, res, buffer);
      if (feof(f))
	return 1;
    }
}