[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