*** empty log message ***
[rsync/rsync.git] / util.c
diff --git a/util.c b/util.c
index 537ec0b..e53d02a 100644 (file)
--- a/util.c
+++ b/util.c
@@ -31,73 +31,77 @@ int num_waiting(int fd)
   return(len);
 }
 
-static int map_fd = -1;
-static off_t map_size = 0;
-static char *p = NULL;
-static int p_size = 0;
-static int p_offset = 0;
-static int p_len = 0;
 
-
-char *map_file(int fd,off_t len)
+struct map_struct *map_file(int fd,off_t len)
 {
-  char *ret = NULL;
+  struct map_struct *ret;
+  ret = (struct map_struct *)malloc(sizeof(*ret));
+  if (!ret) out_of_memory("map_file");
+
+  ret->map = NULL;
+  ret->fd = fd;
+  ret->size = len;
+  ret->p = NULL;
+  ret->p_size = 0;
+  ret->p_offset = 0;
+  ret->p_len = 0;
+
 #ifdef HAVE_MMAP
   if (len < MAX_MAP_SIZE)
-    ret = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
+    ret->map = (char *)mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
 #endif
-  map_fd = fd;
-  map_size = len; 
   return ret;
 }
 
-char *map_ptr(char *buf,off_t offset,int len)
+char *map_ptr(struct map_struct *map,off_t offset,int len)
 {
-  if (buf)
-    return buf+offset;
+  int nread = -2;
+
+  if (map->map)
+    return map->map+offset;
 
   if (len == 0) 
     return NULL;
 
-  len = MIN(len,map_size-offset);
+  len = MIN(len,map->size-offset);
 
-  if (offset >= p_offset && 
-      offset+len <= p_offset+p_len) {
-    return (p + (offset - p_offset));
+  if (offset >= map->p_offset && 
+      offset+len <= map->p_offset+map->p_len) {
+    return (map->p + (offset - map->p_offset));
   }
 
-  len = MAX(len,WRITE_BLOCK_SIZE);
-  len = MIN(len,map_size - offset);  
+  len = MAX(len,CHUNK_SIZE);
+  len = MIN(len,map->size - offset);  
 
-  if (len > p_size) {
-    if (p) free(p);
-    p = (char *)malloc(len);
-    if (!p) out_of_memory("map_ptr");
-    p_size = len;
+  if (len > map->p_size) {
+    if (map->p) free(map->p);
+    map->p = (char *)malloc(len);
+    if (!map->p) out_of_memory("map_ptr");
+    map->p_size = len;
   }
 
-  if (lseek(map_fd,offset,SEEK_SET) != offset ||
-      read(map_fd,p,len) != len) {
-    fprintf(stderr,"EOF in map_ptr!\n");
-    exit(1);
+  if (lseek(map->fd,offset,SEEK_SET) != offset ||
+      (nread=read(map->fd,map->p,len)) != len) {
+    fprintf(FERROR,"EOF in map_ptr! (offset=%d len=%d nread=%d errno=%d)\n",
+           (int)offset, len, nread, errno);
+    exit_cleanup(1);
   }
 
-  p_offset = offset;
-  p_len = len;
+  map->p_offset = offset;
+  map->p_len = len;
 
-  return p; 
+  return map->p; 
 }
 
 
-void unmap_file(char *buf,off_t len)
+void unmap_file(struct map_struct *map)
 {
 #ifdef HAVE_MMAP
-  if (len > 0 && buf)
-    munmap(buf,len);
+  if (map->map)
+    munmap(map->map,map->size);
 #endif
-  map_fd = -1;
-  map_size = 0;
-  p_len = 0;
+  if (map->p) free(map->p);
+  free(map);
 }
 
 
@@ -110,36 +114,40 @@ int piped_child(char **command,int *f_in,int *f_out)
 
   if (pipe(to_child_pipe) < 0 ||
       pipe(from_child_pipe) < 0) {
-    fprintf(stderr,"pipe: %s\n",strerror(errno));
-    exit(1);
+    fprintf(FERROR,"pipe: %s\n",strerror(errno));
+    exit_cleanup(1);
   }
 
 
   pid = fork();
   if (pid < 0) {
-    fprintf(stderr,"fork: %s\n",strerror(errno));
-    exit(1);
+    fprintf(FERROR,"fork: %s\n",strerror(errno));
+    exit_cleanup(1);
   }
 
   if (pid == 0)
     {
+      extern int orig_umask;
       if (dup2(to_child_pipe[0], STDIN_FILENO) < 0 ||
          close(to_child_pipe[1]) < 0 ||
          close(from_child_pipe[0]) < 0 ||
          dup2(from_child_pipe[1], STDOUT_FILENO) < 0) {
-       fprintf(stderr,"Failed to dup/close : %s\n",strerror(errno));
-       exit(1);
+       fprintf(FERROR,"Failed to dup/close : %s\n",strerror(errno));
+       exit_cleanup(1);
       }
+      if (to_child_pipe[0] != STDIN_FILENO) close(to_child_pipe[0]);
+      if (from_child_pipe[1] != STDOUT_FILENO) close(from_child_pipe[1]);
+      umask(orig_umask);
       execvp(command[0], command);
-      fprintf(stderr,"Failed to exec %s : %s\n",
+      fprintf(FERROR,"Failed to exec %s : %s\n",
              command[0],strerror(errno));
-      exit(1);
+      exit_cleanup(1);
     }
 
   if (close(from_child_pipe[1]) < 0 ||
       close(to_child_pipe[0]) < 0) {
-    fprintf(stderr,"Failed to close : %s\n",strerror(errno));   
-    exit(1);
+    fprintf(FERROR,"Failed to close : %s\n",strerror(errno));   
+    exit_cleanup(1);
   }
 
   *f_in = from_child_pipe[0];
@@ -151,8 +159,8 @@ int piped_child(char **command,int *f_in,int *f_out)
 
 void out_of_memory(char *str)
 {
-  fprintf(stderr,"out of memory in %s\n",str);
-  exit(1);
+  fprintf(FERROR,"out of memory in %s\n",str);
+  exit_cleanup(1);
 }
 
 
@@ -220,3 +228,26 @@ int set_blocking(int fd, int set)
   return fcntl( fd, F_SETFL, val);
 #undef FLAG_TO_SET
 }
+
+/****************************************************************************
+create any necessary directories in fname. Unfortunately we don't know
+what perms to give the directory when this is called so we need to rely
+on the umask
+****************************************************************************/
+int create_directory_path(char *fname)
+{
+       extern int orig_umask;
+       char *p;
+
+       while (*fname == '/') fname++;
+       while (strncmp(fname,"./",2)==0) fname += 2;
+
+       p = fname;
+       while ((p=strchr(p,'/'))) {
+               *p = 0;
+               mkdir(fname,0777 & ~orig_umask); 
+               *p = '/';
+               p++;
+       }
+       return 0;
+}