[or-cvs] Refactor common file code into util.c; add published to des...

Nick Mathewson nickm at seul.org
Fri Sep 26 18:27:37 UTC 2003


Update of /home/or/cvsroot/src/common
In directory moria.mit.edu:/tmp/cvs-serv18107/common

Modified Files:
	crypto.c crypto.h util.c util.h 
Log Message:
Refactor common file code into util.c; add published to descriptors

Index: crypto.c
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -r1.35 -r1.36
--- crypto.c	25 Sep 2003 05:17:10 -0000	1.35
+++ crypto.c	26 Sep 2003 18:27:34 -0000	1.36
@@ -472,6 +472,28 @@
   return 0;
 }
 
+int 
+crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, 
+                                        const char *fname)
+{
+  BIO *bio;
+  char *cp;
+  long len;
+  int r;
+  assert(env->type == CRYPTO_PK_RSA);
+  if (!(bio = BIO_new(BIO_s_mem())))
+    return -1;
+  if (PEM_write_bio_RSAPrivateKey(bio, (RSA*)env->key, NULL,NULL,0,0,NULL)) {
+    BIO_free(bio);
+    return -1;
+  }
+  len = BIO_get_mem_data(bio, &cp);
+  assert(len == strlen(cp));
+  r = write_str_to_file(fname, cp);
+  BIO_free(bio);
+  return r;
+}
+
 int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest)
 {
   assert(env && dest);

Index: crypto.h
===================================================================
RCS file: /home/or/cvsroot/src/common/crypto.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- crypto.h	25 Sep 2003 05:17:10 -0000	1.17
+++ crypto.h	26 Sep 2003 18:27:34 -0000	1.18
@@ -40,6 +40,7 @@
 int crypto_pk_write_public_key_to_string(crypto_pk_env_t *env, char **dest, int *len);
 int crypto_pk_read_public_key_from_string(crypto_pk_env_t *env, char *src, int len);
 int crypto_pk_write_private_key_to_file(crypto_pk_env_t *env, FILE *dest);
+int crypto_pk_write_private_key_to_filename(crypto_pk_env_t *env, const char *fname);
 int crypto_pk_write_public_key_to_file(crypto_pk_env_t *env, FILE *dest);
 int crypto_pk_check_key(crypto_pk_env_t *env);
 int crypto_pk_read_private_key_from_filename(crypto_pk_env_t *env, const char *keyfile);

Index: util.c
===================================================================
RCS file: /home/or/cvsroot/src/common/util.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- util.c	14 Sep 2003 02:58:47 -0000	1.17
+++ util.c	26 Sep 2003 18:27:34 -0000	1.18
@@ -13,6 +13,10 @@
 #include "util.h"
 #include "log.h"
 
+/*
+ *    Memory
+ */
+
 void *tor_malloc(size_t size) {
   void *result;
 
@@ -26,6 +30,10 @@
   return result;
 }
 
+/*
+ *    Time
+ */
+
 void 
 my_gettimeofday(struct timeval *timeval) 
 {
@@ -88,6 +96,10 @@
   a->tv_usec %= 1000000;
 }
 
+/*
+ *   Low-level I/O.
+ */
+
 /* a wrapper for write(2) that makes sure to write all count bytes.
  * Only use if fd is a blocking socket. */
 int write_all(int fd, const void *buf, size_t count) {
@@ -129,6 +141,10 @@
 #endif
 }
 
+/*
+ *   Process control
+ */
+
 int spawn_func(int (*func)(void *), void *data)
 {
 #ifdef MS_WINDOWS
@@ -164,7 +180,9 @@
 }
 
 
-/* Fake socket pair over TCP.  Code adapted from perl 5.8.0's util.c */
+/*
+ *   Windows compatibility.
+ */
 int
 tor_socketpair(int family, int type, int protocol, int fd[2])
 {
@@ -276,3 +294,100 @@
   return WSAEWOULDBLOCK;
 }
 #endif
+
+/*
+ *    Filesystem operations.
+ */
+file_status_t file_status(const char *fname)
+{
+  struct stat st;
+  if (stat(fname, &st)) {
+    if (errno == ENOENT) {
+      return FN_NOENT;
+    }
+    return FN_ERROR;
+  }
+  if (st.st_mode & S_IFDIR) 
+    return FN_DIR;
+  else if (st.st_mode & S_IFREG)
+    return FN_FILE;
+  else
+    return FN_ERROR;
+}
+
+int check_private_dir(const char *dirname, int create)
+{
+  struct stat st;
+  if (stat(dirname, &st)) {
+    if (errno != ENOENT) {
+      log(LOG_ERR, "Directory %s cannot be read: %s", dirname, 
+          strerror(errno));
+      return -1;
+    } 
+    if (!create) {
+      log(LOG_ERR, "Directory %s does not exist.", dirname);
+      return -1;
+    }
+    log(LOG_INFO, "Creating directory %s", dirname); 
+    if (mkdir(dirname, 0700)) {
+      log(LOG_ERR, "Error creating directory %s: %s", dirname, 
+          strerror(errno));
+      return -1;
+    } else {
+      return 0;
+    }
+  }
+  if (!(st.st_mode & S_IFDIR)) {
+    log(LOG_ERR, "%s is not a directory", dirname);
+    return -1;
+  }
+  if (st.st_uid != getuid()) {
+    log(LOG_ERR, "%s is not owned by this UID (%d)", dirname, getuid());
+    return -1;
+  }
+  if (st.st_mode & 0077) {
+    log(LOG_WARNING, "Fixing permissions on directory %s", dirname);
+    if (chmod(dirname, 0700)) {
+      log(LOG_ERR, "Could not chmod directory %s: %s", dirname, 
+          strerror(errno));
+      return -1;
+    } else {
+      return 0;
+    }
+  }
+  return 0;
+}
+
+int
+write_str_to_file(const char *fname, const char *str)
+{
+  char tempname[1024];
+  int fd;
+  FILE *file;
+  if (strlen(fname) > 1000) {
+    log(LOG_ERR, "Filename %s is too long.", fname);
+    return -1;
+  }
+  strcpy(tempname,fname);
+  strcat(tempname,".tmp");
+  if ((fd = open(tempname, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
+    log(LOG_ERR, "Couldn't open %s for writing: %s", tempname, 
+        strerror(errno));
+    return -1;
+  }
+  if (!(file = fdopen(fd, "w"))) {
+    log(LOG_ERR, "Couldn't fdopen %s for writing: %s", tempname, 
+        strerror(errno));
+    close(fd); return -1;
+  }
+  if (fputs(str,file)) {
+    log(LOG_ERR, "Error writing to %s: %s", tempname, strerror(errno));
+    fclose(file); return -1;
+  }
+  fclose(file);
+  if (rename(tempname, fname)) {
+    log(LOG_ERR, "Error replacing %s: %s", fname, strerror(errno));
+    return -1;
+  }
+  return 0;
+}

Index: util.h
===================================================================
RCS file: /home/or/cvsroot/src/common/util.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- util.h	14 Sep 2003 02:58:47 -0000	1.11
+++ util.h	26 Sep 2003 18:27:34 -0000	1.12
@@ -56,6 +56,18 @@
 
 void set_socket_nonblocking(int socket);
 
+typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR} file_status_t;
+
+/* Return FN_ERROR if filename can't be read, FN_NOENT if it doesn't
+ * exist, FN_FILE if it is a regular file, or FN_DIR if it's a
+ * directory. */
+file_status_t file_status(const char *filename);
+/* Check whether dirname exists and is private.  If yes returns
+ * 0.  Else returns -1.
+ */
+int check_private_dir(const char *dirname, int create);
+int write_str_to_file(const char *fname, const char *str);
+
 /* Minimalist interface to run a void function in the background.  On
    unix calls fork, on win32 calls beginthread.  Returns -1 on failure.
    func should not return, but rather should call spawn_exit.



More information about the tor-commits mailing list