Start of "patch" support. Writes to stdout at the moment.
authorRob Landley <rob@landley.net>
Sun, 16 Dec 2007 03:47:25 +0000 (21:47 -0600)
committerRob Landley <rob@landley.net>
Sun, 16 Dec 2007 03:47:25 +0000 (21:47 -0600)
lib/lib.c
lib/lib.h
toys/Config.in
toys/toylist.h

index 389adcd..547fe40 100644 (file)
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -192,6 +192,11 @@ int xopen(char *path, int flags)
        return xcreate(path, flags, 0);
 }
 
+void xclose(int fd)
+{
+       if (close(fd)) perror_exit("xclose");
+}
+
 // Die unless we can open/create a file, returning FILE *.
 FILE *xfopen(char *path, char *mode)
 {
@@ -567,3 +572,46 @@ void loopfiles(char **argv, void (*function)(int fd, char *name))
                close(fd);
        } while (*++argv);
 }
+
+// Slow, but small.
+
+char *get_rawline(int fd, long *plen)
+{
+       char c, *buf = NULL;
+       long len = 0;
+
+       for (;;) {
+               if (1>read(fd, &c, 1)) break;
+               if (!(len & 63)) buf=xrealloc(buf, len+64);
+               if ((buf[len++]=c) == '\n') break;
+       }
+       if (buf) buf[len]=0;
+       if (plen) *plen = len;
+
+       return buf;
+}
+
+char *get_line(int fd)
+{
+       long len;
+       char *buf = get_rawline(fd, &len);
+
+       if (buf && buf[--len]=='\n') buf[len]=0;
+
+       return buf;
+}
+
+// Copy the rest of in to out and close both files.
+
+void xsendfile(int in, int out)
+{
+       long len;
+
+       if (in<0) return;
+       for (;;) {
+               len = xread(in, toybuf, sizeof(toybuf));
+               if (len<1) break;
+               xwrite(out, toybuf, len);
+       }
+       xclose(in);
+}
index 963abb6..063c5d0 100644 (file)
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -21,6 +21,12 @@ struct arg_list {
        char *arg;
 };
 
+struct double_list {
+       struct double_list *next;
+       struct double_list *prev;
+       char *data;
+};
+
 // args.c
 void get_optflags(void);
 
@@ -56,6 +62,7 @@ void xexec(char **argv);
 void xaccess(char *path, int flags);
 int xcreate(char *path, int flags, int mode);
 int xopen(char *path, int flags);
+void xclose(int fd);
 FILE *xfopen(char *path, char *mode);
 ssize_t readall(int fd, void *buf, size_t len);
 ssize_t writeall(int fd, void *buf, size_t len);
@@ -74,6 +81,9 @@ long atolx(char *c);
 off_t fdlength(int fd);
 char *xreadlink(char *name);
 void loopfiles(char **argv, void (*function)(int fd, char *name));
+char *get_rawline(int fd, long *plen);
+char *get_line(int fd);
+void xsendfile(int in, int out);
 
 // getmountlist.c
 struct mtab_list {
index 8f2cf6c..3d1b168 100644 (file)
@@ -273,6 +273,19 @@ config ONEIT
          own session.  Then oneit reaps zombies until the child exits, at
          which point it reboots (or with -p, powers off) the system.
 
+config PATCH
+       bool "patch"
+       default n
+       help
+         usage: patch [-i file] [-p depth] [-Ru]
+
+         Apply a unified diff to one or more files.
+
+         -i    Input file (defaults=stdin)
+         -p    number of '/' to strip from start of file paths (default=all)
+         -R    Reverse patch.
+         -u    Ignored (only handles "unified" diffs)
+
 config PWD
        bool "pwd"
        default y
index 9d04026..9b99202 100644 (file)
@@ -67,6 +67,16 @@ struct oneit_data {
        char *console;
 };
 
+struct patch_data {
+       char *infile;
+       long prefix;
+
+       struct double_list *plines, *flines;
+       long oldline, oldlen, newline, newlen;
+       int context, state;
+       int filein, fileout, filepatch;
+};
+
 struct sleep_data {
        long seconds;
 };
@@ -92,6 +102,7 @@ extern union toy_union {
        struct mkfifo_data mkfifo;
        struct netcat_data netcat;
        struct oneit_data oneit;
+       struct patch_data patch;
        struct sleep_data sleep;
        struct touch_data touch;
        struct toysh_data toysh;
@@ -140,6 +151,7 @@ USE_MKFIFO(NEWTOY(mkfifo, "<1m:", TOYFLAG_BIN))
 USE_NETCAT(OLDTOY(nc, netcat, "i#w#l@p#s:q#f:e", TOYFLAG_BIN))
 USE_NETCAT(NEWTOY(netcat, "i#w#l@p#s:q#f:e", TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "+<1c:p", TOYFLAG_SBIN))
+USE_PATCH(NEWTOY(patch, "up#i:R", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PWD(NEWTOY(pwd, NULL, TOYFLAG_BIN))
 USE_READLINK(NEWTOY(readlink, "<1f", TOYFLAG_BIN))
 USE_TOYSH(OLDTOY(sh, toysh, "c:i", TOYFLAG_BIN))