]> git.neil.brown.name Git - wiggle.git/blobdiff - load.c
Disable *all* backups when --no-backups used
[wiggle.git] / load.c
diff --git a/load.c b/load.c
index 27275c9e9a9c188edc0a2d5acee71311f3aa9afb..291000cea78de838ec03908d4277422167318b4f 100644 (file)
--- a/load.c
+++ b/load.c
@@ -2,6 +2,8 @@
  * wiggle - apply rejected patches
  *
  * Copyright (C) 2003 Neil Brown <neilb@cse.unsw.edu.au>
+ * Copyright (C) 2013 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2014-2020 Neil Brown <neil@brown.name>
  *
  *
  *    This program is free software; you can redistribute it and/or modify
  *    GNU General Public License for more details.
  *
  *    You should have received a copy of the GNU General Public License
- *    along with this program; if not, write to the Free Software
- *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *    along with this program.
  *
  *    Author: Neil Brown
- *    Email: <neilb@cse.unsw.edu.au>
- *    Paper: Neil Brown
- *           School of Computer Science and Engineering
- *           The University of New South Wales
- *           Sydney, 2052
- *           Australia
+ *    Email: <neil@brown.name>
  */
 
 /*
 #include       <sys/stat.h>
 #include       <unistd.h>
 #include       <fcntl.h>
-#include       <malloc.h>
+#include       <stdlib.h>
 
 static void join_streams(struct stream list[], int cnt)
 {
        /* join all the streams in the list (upto body=NULL)
         * into one by re-allocing list[0].body and copying
         */
-       int len=0;
+       int len = 0;
        int i;
        char *c;
 
-       for (i=0; i<cnt ; i++)
+       for (i = 0; i < cnt ; i++)
                len += list[i].len;
 
-       c = realloc(list[0].body, len);
+       c = realloc(list[0].body, len+1);
        if (c == NULL)
-               die();
+               wiggle_die("memory allocation");
 
        list[0].body = c;
        c  += list[0].len;
        list[0].len = len;
-       for (i=1; i<cnt; i++) {
+       for (i = 1; i < cnt; i++) {
                memcpy(c, list[i].body, list[i].len);
                c += list[i].len;
                list[i].len = 0;
+               free(list[i].body);
        }
+       c[0] = 0;
 }
 
-static struct stream load_regular(int fd)
+static struct stream wiggle_load_regular(int fd)
 {
        struct stat stb;
        struct stream s;
        fstat(fd, &stb);
 
        s.len = stb.st_size;
-       s.body = malloc(s.len);
-       if (s.body) {
-               if (read(fd, s.body, s.len) != s.len) {
-                       free(s.body);
-                       s.body = NULL;
-               }
-       } else die();
+       s.body = wiggle_xmalloc(s.len+1);
+       if (read(fd, s.body, s.len) != s.len)
+               wiggle_die("file read");
+
+       s.body[s.len] = 0;
        return s;
 }
 
-static struct stream load_other(int fd)
+static struct stream wiggle_load_other(int fd)
 {
 
        struct stream list[10];
        int i = 0;
 
-       while(1) {
-               list[i].body = malloc(8192);
-               if (!list[i].body)
-                       die();
+       while (1) {
+               list[i].body = wiggle_xmalloc(8192);
                list[i].len = read(fd, list[i].body, 8192);
                if (list[i].len < 0)
-                       die();
+                       wiggle_die("file read");
                if (list[i].len == 0)
                        break;
                i++;
@@ -113,30 +107,58 @@ static struct stream load_other(int fd)
        return list[0];
 }
 
-struct stream load_file(char *name)
+struct stream wiggle_load_segment(FILE *f,
+                          unsigned int start, unsigned int end)
+{
+       struct stream s;
+       s.len = end - start;
+       s.body = wiggle_xmalloc(s.len+1);
+       fseek(f, start, 0);
+       if (fread(s.body, 1, s.len, f) != (size_t)s.len)
+               wiggle_die("file read");
+       /* ensure string is 'nul' terminated - for sscanf */
+       s.body[s.len] = 0;
+       return s;
+}
+
+struct stream wiggle_load_file(char *name)
 {
        struct stream s;
        struct stat stb;
        int fd;
+       int start, end;
+       int prefix_len = 0;
 
        s.body = NULL;
        s.len = 0;
-       if (strcmp(name, "-")==0)
-               fd = 0;
-       else {
-               fd = open(name, O_RDONLY);
-               if (fd <0)
-                       return s;
-       }
-
-       if (fstat(fd, &stb) == 0) {
+       if (sscanf(name, "_wiggle_:%d:%d:%n", &start, &end,
+                  &prefix_len) >= 2 && prefix_len > 0) {
+               FILE *f = fopen(name + prefix_len, "r");
+               if (f) {
+                       s = wiggle_load_segment(f, start, end);
+                       fclose(f);
+               } else {
+                       s.body = NULL;
+                       s.len = 0;
+               }
+       } else {
+               if (strcmp(name, "-") == 0)
+                       fd = 0;
+               else {
+                       fd = open(name, O_RDONLY);
+                       if (fd < 0)
+                               return s;
+               }
+               wiggle_check_dir(name, fd);
+               if (fstat(fd, &stb) == 0) {
 
-               if (S_ISREG(stb.st_mode))
-                       s = load_regular(fd);
-               else
-                       s = load_other(fd);
+                       if (S_ISREG(stb.st_mode))
+                               s = wiggle_load_regular(fd);
+                       else
+                               s = wiggle_load_other(fd);
+               }
+               close(fd);
        }
-       close(fd);
        return s;
 }