2 * Copyright (C) 2008 Edwin Groothuis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
29 #include <sys/types.h>
32 #include <netinet/in.h>
33 #include <arpa/tftp.h>
42 #include "tftp-file.h"
43 #include "tftp-utils.h"
48 static char convbuffer[66000];
52 convert_from_net(char *buffer, size_t count)
57 * Convert all CR/LF to LF and all CR,NUL to CR
61 for (i = 0; i < count; i++) {
64 convbuffer[n++] = buffer[i];
65 gotcr = (buffer[i] == '\r');
70 if (buffer[i] == '\0') {
76 if (buffer[i] == '\n') {
78 if (ftell(file) != 0) {
79 fseek(file, -1, SEEK_END);
80 convbuffer[n++] = '\n';
82 /* This shouldn't happen */
84 "Received LF as first character");
88 convbuffer[n-1] = '\n';
93 /* Everything else just accept as is */
94 convbuffer[n++] = buffer[i];
95 gotcr = (buffer[i] == '\r');
99 return fwrite(convbuffer, 1, n, file);
103 convert_to_net(char *buffer, size_t count, int init)
106 static size_t n = 0, in = 0;
107 static int newline = 0;
117 * Convert all LF to CR,LF and all CR to CR,NUL
122 buffer[i++] = newline;
128 /* When done we're done */
129 if (feof(file)) break;
131 /* Otherwise read another bunch */
132 in = fread(convbuffer, 1, count, file);
138 if (convbuffer[n] == '\r') {
146 if (convbuffer[n] == '\n') {
153 buffer[i++] = convbuffer[n++];
158 * Whoops... that isn't alllowed (but it will happen
159 * when there is a CR or LF at the end of the buffer)
161 newline = buffer[i-1];
173 write_init(int fd, FILE *f, const char *mode)
177 file = fdopen(fd, "w");
180 tftp_log(LOG_ERR, "fdopen() failed: %s",
186 convert = !strcmp(mode, "netascii");
191 write_file(char *buffer, int count)
195 return fwrite(buffer, 1, count, file);
197 return convert_from_net(buffer, count);
204 if (fclose(file) != 0) {
205 tftp_log(LOG_ERR, "fclose() failed: %s", strerror(errno));
212 read_init(int fd, FILE *f, const char *mode)
215 convert_to_net(NULL, 0, 1);
217 file = fdopen(fd, "r");
220 tftp_log(LOG_ERR, "fdopen() failed: %s",
226 convert = !strcmp(mode, "netascii");
231 read_file(char *buffer, int count)
235 return fread(buffer, 1, count, file);
237 return convert_to_net(buffer, count, 0);
244 if (fclose(file) != 0) {
245 tftp_log(LOG_ERR, "fclose() failed: %s", strerror(errno));
253 synchnet(int peer __unused)