From bc07865a504c291b9c88e41b3481ee6b44334b4d Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sat, 15 Dec 2007 21:47:25 -0600 Subject: Start of "patch" support. Writes to stdout at the moment. --- lib/lib.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/lib.h | 10 ++++++++++ toys/Config.in | 13 +++++++++++++ toys/toylist.h | 12 ++++++++++++ 4 files changed, 83 insertions(+) diff --git a/lib/lib.c b/lib/lib.c index 389adcdc..547fe400 100644 --- 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); +} diff --git a/lib/lib.h b/lib/lib.h index 963abb68..063c5d02 100644 --- 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 { diff --git a/toys/Config.in b/toys/Config.in index 8f2cf6c5..3d1b168d 100644 --- a/toys/Config.in +++ b/toys/Config.in @@ -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 diff --git a/toys/toylist.h b/toys/toylist.h index 9d040265..9b992028 100644 --- a/toys/toylist.h +++ b/toys/toylist.h @@ -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)) -- cgit v1.2.3