aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/lib.c48
-rw-r--r--lib/lib.h10
-rw-r--r--toys/Config.in13
-rw-r--r--toys/toylist.h12
4 files changed, 83 insertions, 0 deletions
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))