]> andersk Git - moira.git/blobdiff - update/send_file.c
Command line printer manipulation client, and build goo.
[moira.git] / update / send_file.c
index 6772736fd39c71b70fff3a3efcbbb3bc36b1b099..49127f41b2f02b5c58013f4245e304440d73fa0a 100644 (file)
@@ -1,25 +1,32 @@
-/*
- *     $Source$
- *     $Header$
+/* $Id$
+ *
+ * Copyright (C) 1988-1998 by the Massachusetts Institute of Technology.
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
  */
 
-#ifndef lint
-static char *rcsid_send_file_c = "$Header$";
-#endif lint
+#include <mit-copyright.h>
+#include <moira.h>
+#include "update_server.h"
+
+#include <sys/stat.h>
 
+#include <errno.h>
+#include <fcntl.h>
 #include <stdio.h>
-#include "com_err.h"
-#include "gdb.h"
-#include "smsu_int.h"
-#include <sys/file.h>
-#include "update.h"
-#include "sms_update_int.h"
-#include "kludge.h"
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_KRB4
+#include <des.h>
+#endif
+#include <update.h>
+
+RCSID("$Header$");
 
-extern CONNECTION conn;
-extern int errno;
-char buf[BUFSIZ];
-extern struct update_desc *info;
+#ifdef HAVE_KRB4
+extern des_cblock session;
+#endif
 
 /*
  * syntax:
@@ -38,76 +45,152 @@ extern struct update_desc *info;
  *  1 on error (file not found, etc)
  */
 
-int
-send_file(pathname, n_to_send)
-    char *pathname;
-    int n_to_send;
+int mr_send_file(int conn, char *pathname, char *target_path, int encrypt)
 {
-    int n, fd, code;
-    STRING data;
+  int n, fd, code, n_to_send, i;
+  char data[UPDATE_BUFSIZ], enc[UPDATE_BUFSIZ];
+  long response;
+  struct stat statb;
+#ifdef HAVE_KRB4
+  des_key_schedule sched;
+  des_cblock ivec;
+#endif
+
+  /* send file over */
+  fd = open(pathname, O_RDONLY, 0);
+  if (fd < 0)
+    {
+      com_err(whoami, errno, "unable to open %s for read", pathname);
+      return MR_OCONFIG;
+    }
+  if (fstat(fd, &statb))
+    {
+      com_err(whoami, errno, "unable to stat %s", pathname);
+      close(fd);
+      return MR_OCONFIG;
+    }
+  n_to_send = statb.st_size;
+
+  sprintf(data, "XFER_00%c %d %d %s", (encrypt ? '3' : '2'), n_to_send,
+         checksum_file(pathname), target_path);
+  code = send_string(conn, data, strlen(data) + 1);
+  if (code)
+    {
+      com_err(whoami, code, "sending XFER request");
+      close(fd);
+      return code;
+    }
+  code = recv_int(conn, &response);
+  if (code)
+    {
+      com_err(whoami, code, "getting reply from XFER request");
+      close(fd);
+      return code;
+    }
+  if (response)
+    {
+      com_err(whoami, response, "transfer request (XFER) rejected");
+      close(fd);
+      return response;
+    }
 
-    fd = open(pathname, O_RDONLY, 0);
-    if (fd == -1) {
-       sprintf(buf, "%s: can't open %s for transmission",
-               error_message(errno), pathname);
-       sms_log_error(buf);
-       return(1);
+  code = recv_int(conn, &response);
+  if (code)
+    {
+      com_err(whoami, code, ": lost connection");
+      close(fd);
+      return code;
     }
-    code = receive_object(conn, (char *)&n, INTEGER_T);
-    if (code) {
-       com_err(whoami, connection_errno(conn), ": lost connection");
-       info->override = INTERVAL_connection_lost;
-       close(fd);
-       return(1);
+  if (response)
+    {
+      com_err(whoami, response, " from remote server: can't update %s",
+             pathname);
+      close(fd);
+      return response;
     }
-    if (n) {
-       log_priority = log_ERROR;
-       com_err(whoami, n, ": from remote server: can't update %s",
-               pathname);
-       info->override = INTERVAL_update_failed;
-       close(fd);
-       return(1);
+
+  if (encrypt)
+    {
+#ifdef HAVE_KRB4
+      des_key_sched(session, sched);
+      memmove(ivec, session, sizeof(ivec));
+#else
+      /* The session key only gets stored if auth happens in krb4 to
+         begin with. If you don't have krb4, you can't possibly be
+         coming up with a valid session key. */
+      return MR_NO_KRB4;
+#endif
     }
-    string_alloc(&data, UPDATE_BUFSIZ);
-    while (n_to_send > 0) {
-#ifdef DEBUG
-       printf("n_to_send = %d\n", n_to_send);
-#endif /* DEBUG */
-       n = read(fd, STRING_DATA(data), UPDATE_BUFSIZ);
-       if (n < 0) {
-           sprintf(buf, "%s: reading %s for transmission",
-                   error_message(errno), pathname);
-           sms_log_error(buf);
-           close(fd);
-           return(1);
+
+  while (n_to_send > 0)
+    {
+      n = read(fd, data, sizeof(data));
+      if (n < 0)
+       {
+         com_err(whoami, errno, "reading %s for transmission", pathname);
+         close(fd);
+         return MR_ABORTED;
+       }
+      if (encrypt)
+       {
+#ifdef HAVE_KRB4
+         memset(data + n, 0, sizeof(data) -n);
+         des_pcbc_encrypt(data, enc, (n + 7) & ~7, sched, ivec, 0);
+         /* save vector to continue chaining */
+         for (i = 0; i < 8; i++)
+           ivec[i] = data[n - 8 + i] ^ enc[n - 8 + i];
+         /* round up to multiple of 8 */
+         n = (n + 7) & ~7;
+         code = send_string(conn, enc, n);
+#endif
        }
-       MAX_STRING_SIZE(data) = n;
-       code = send_object(conn, (char *)&data, STRING_T);
-       if (code) {
-           sprintf(buf, "%s: transmitting file %s",
-                   error_message(connection_errno(conn)), pathname);
-           sms_log_error(buf);
-           close(fd);
-           return(1);
+      else
+       code = send_string(conn, data, n);
+      if (code)
+       {
+         com_err(whoami, code, "transmitting file %s", pathname);
+         close(fd);
+         return code;
        }
-       n_to_send -= n;
-       code = receive_object(conn, (char *)&n, INTEGER_T);
-       if (code) {
-           sprintf(buf,
-                   "%s: awaiting ACK remote server during transmission of %s",
-                   error_message(connection_errno(conn)), pathname);
-           sms_log_error(buf);
-           close(fd);
-           return(1);
+
+      n_to_send -= n;
+      code = recv_int(conn, &response);
+      if (code)
+       {
+         com_err(whoami, code, "awaiting ACK during transmission of %s",
+                 pathname);
+         close(fd);
+         return code;
+       }
+      if (response)
+       {
+         com_err(whoami, response,
+                 "from remote server during transmission of %s",
+                 pathname);
+         close(fd);
+         return response;
+       }
+    }
+
+  if (statb.st_size == 0)
+    {
+      code = recv_int(conn, &response);
+      if (code)
+       {
+         com_err(whoami, code, "awaiting ACK after transmission of %s",
+                 pathname);
+         close(fd);
+         return code;
        }
-       if (n) {
-           sprintf(buf, "%s: from remote server during transmission of %s",
-                   error_message(n), pathname);
-           sms_log_error(buf);
-           close(fd);
-           return(1);
+      if (response)
+       {
+         com_err(whoami, response,
+                 "from remote server after transmission of %s",
+                 pathname);
+         close(fd);
+         return response;
        }
     }
-    close(fd);
-    return(0);
+  close(fd);
+  return MR_SUCCESS;
 }
This page took 0.049281 seconds and 4 git commands to generate.