#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <des.h>
-#include <gdb.h>
RCSID("$Header$");
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif /* MIN */
-extern CONNECTION conn;
-extern char buf[BUFSIZ];
-
-extern int code, uid;
-extern char *whoami;
-
-extern int have_authorization, have_file, done;
-extern C_Block session;
static des_key_schedule sched;
static des_cblock ivec;
+extern des_cblock session;
-static int get_block(int fd, int max_size, int encrypt);
+static int get_block(int conn, int fd, int max_size, int encrypt);
/*
* get_file()
*
*/
-int get_file(char *pathname, int file_size, int checksum,
+int get_file(int conn, char *pathname, int file_size, int checksum,
int mode, int encrypt)
{
- int fd, n_written;
+ int fd, n_written, code;
int found_checksum;
+ char buf[BUFSIZ];
if (!have_authorization)
{
- reject_call(MR_PERM);
+ send_int(conn, MR_PERM);
return 1;
}
- if (done) /* re-initialize data */
- initialize();
if (setuid(uid) < 0)
{
com_err(whoami, errno, "Unable to setuid to %d\n", uid);
exit(1);
}
+
/* unlink old file */
if (!config_lookup("noclobber"))
unlink(pathname);
if (fd == -1)
{
code = errno;
- sprintf(buf, "%s: creating file %s (get_file)",
- error_message(code), pathname);
- mr_log_error(buf);
- report_error("reporting file creation error (get_file)");
+ com_err(whoami, errno, "creating file %s (get_file)", pathname);
+ send_int(conn, code);
if (setuid(0) < 0)
{
com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
}
return 1;
}
+
/* check to see if we've got the disk space */
n_written = 0;
while (n_written < file_size)
if (n_wrote == -1)
{
code = errno;
- sprintf(buf, "%s: verifying free disk space for %s (get_file)",
- error_message(code), pathname);
- mr_log_error(buf);
+ com_err(whoami, code, "verifying free disk space for %s (get_file)",
+ pathname);
+ send_int(conn, code);
+
/* do all we can to free the space */
unlink(pathname);
ftruncate(fd, 0);
close(fd);
- report_error("reporting test-write error (get_file)");
+
if (setuid(0) < 0)
{
com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
}
n_written += n_wrote;
}
+
lseek(fd, 0, SEEK_SET);
- if (send_ok())
- lose("sending okay for file transfer (get_file)");
+ send_ok(conn);
+
if (encrypt)
{
des_key_sched(session, sched);
memcpy(ivec, session, sizeof(ivec));
}
+
n_written = 0;
- while (n_written < file_size && code == 0)
+ while (n_written < file_size)
{
- int n_got = get_block(fd, file_size - n_written, encrypt);
+ int n_got = get_block(conn, fd, file_size - n_written, encrypt);
+
if (n_got == -1)
{
/* get_block has already printed a message */
}
n_written += n_got;
if (n_written != file_size)
- {
- if (send_ok())
- lose("receiving data");
- }
- }
- if (code)
- {
- code = connection_errno(conn);
- report_error("reading file (get_file)");
- if (setuid(0) < 0)
- {
- com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
- exit(1);
- }
- return 1;
+ send_ok(conn);
}
+
fsync(fd);
ftruncate(fd, file_size);
fsync(fd);
close(fd);
+
if (setuid(0) < 0)
{
com_err(whoami, errno, "Unable to setuid back to %d\n", 0);
exit(1);
}
+
/* validate checksum */
found_checksum = checksum_file(pathname);
if (checksum != found_checksum)
code = MR_MISSINGFILE;
com_err(whoami, code, ": expected = %d, found = %d",
checksum, found_checksum);
- report_error("checksum error");
- return 1;
- }
- /* send ack or nack */
- have_file = 1;
- if (send_ok())
- {
- code = connection_errno(conn);
- unlink(pathname);
- lose("sending ok after file transfer (get_file)");
+ send_int(conn, code);
return 1;
}
+
+ send_ok(conn);
return 0;
}
-static int get_block(int fd, int max_size, int encrypt)
+static int get_block(int conn, int fd, int max_size, int encrypt)
{
- STRING data;
- unsigned char dst[UPDATE_BUFSIZ + 8], *src;
- int n_read, n, i;
+ char *data;
+ size_t len;
+ int n_read, n, i, code;
- code = receive_object(conn, (char *)&data, STRING_T);
- if (code)
- {
- code = connection_errno(conn);
- lose("receiving data file (get_file)");
- }
+ recv_string(conn, &data, &len);
if (encrypt)
{
- src = (unsigned char *)STRING_DATA(data);
- n = MAX_STRING_SIZE(data);
- des_pcbc_encrypt(src, dst, n, sched, ivec, 1);
+ char *unenc = malloc(len);
+
+ if (!unenc)
+ {
+ send_int(conn, ENOMEM);
+ return -1;
+ }
+
+ des_pcbc_encrypt(data, unenc, len, sched, ivec, 1);
for (i = 0; i < 8; i++)
- ivec[i] = src[n - 8 + i] ^ dst[n - 8 + i];
- memcpy(STRING_DATA(data), dst, n);
+ ivec[i] = data[len - 8 + i] ^ unenc[len - 8 + i];
+ free(data);
+ data = unenc;
}
- n_read = MIN(MAX_STRING_SIZE(data), max_size);
+ n_read = MIN(len, max_size);
n = 0;
while (n < n_read)
{
int n_wrote;
- n_wrote = write(fd, STRING_DATA(data) + n, n_read - n);
+ n_wrote = write(fd, data + n, n_read - n);
if (n_wrote == -1)
{
code = errno;
- sprintf(buf, "%s: writing file (get_file)", error_message(code));
- mr_log_error(buf);
- string_free(&data);
- report_error("reporting write error (get_file)");
+ com_err(whoami, errno, "writing file (get_file)");
+ send_int(conn, code);
+ free(data);
close(fd);
return -1;
}
n += n_wrote;
}
- string_free(&data);
+ free(data);
return n;
}